I have a wrapper class that is meant to get and set code from a property in one of my dbml's partial classes. The reason for the wrapper is for a specialized get, which pre-formats the value. Here's what the wrapper looks like (NOTE: this is not the actual code, but represents everything but the formatting accurately):
partial class Class1
{
public string PropertyFormatted
{
get
{
var ret = Property.Substring(1);
return ret;
}
set { Property = value; }
}
}
This wrapper is bound using Bind() in a formview for the edit page. For some reason, the wrapper's value is set twice on update and the second time through the value is re-assigned its original value (causing the property to remain, ultimately, unchanged). However, when the wrapper is replaced with the property itself, there is no problem with saving to the database.
Any ideas what may be the cause of this?
The dbContext should be automatically detecting changes via this method:
http://msdn.microsoft.com/en-us/library/system.data.entity.infrastructure.dbchangetracker.detectchanges(v=vs.103).aspx
You may have inadvertently disable auto detect changes or something of the like. Try manually calling the method and see if that makes a difference.
Good luck!
Related
I'm new to OOP and Yii2. I have a function in Model:
public function getDatRev() {
if ($this->rev) {
return $this->rev;
} else {
return $this->datum;
}
}
in the View until now I have used it like this:
$model->datRev;
and it would return the correct value. Now I don't know what has changed, maybe I was also updated the framework, but the old construct doesn't work anymore, and in order to make it work I have to change it to:
$model->getDatRev();
Can you please explain to me why that is?
When you try get property the Yii2 calls magic method __get (). Return value is depend from implementation of this method in parent class. Yii2 can check if this property exist in some container, or if exist getter of this property.
In your case seems like you don't call parent's method __get(). This may have happened because you override __get() method or initialized this property.
Your class needs to extend yii\base\Object (directly or not) in order to use short property syntax ($model->abc instead of $model->getAbc()). Magic method __get() #Timur mentioned is defined there and further extended in yii\base\Component class.
We use the following general pattern with Grails controllers and command objects
SomeController {
def someAction() {
SomeCommandObject co = SomeCommandObject.valueOf(params)
if(!co.validate()) {
// return bad request
}
someService.doWork(co)
// return ok
}
SomeService {
def doWork(SomeCommandObject co) {
notTrue(!co.hasErrors(), 'cant have errors') // Commons validation
// do actual work
}
}
Apparently, if co.validate() has not been called, .hasErrors() will always return false. Is there a better way to enforce that .validate() has been called before a command object is passed between application layers? We don't want to pass around invalid command objects but we don't want to force every new method to re-validate the command object either.
Note: We aren't using the default controller/command object creation pattern because we need to do some custom parameter map checking, we use a static valueOf method instead to create the command object. Answers that change that practice are also welcome.
EDIT: A little more info on why we aren't using the 'default' controller/command object creation. Specifically why we aren't doing ..
def someAction(SomeCommandObject co) {
}
We have a requirement to disallow random query parameters, eg. endpoint/object?color=blue. To do that we need access to the parameter map in the command object to verify that it doesn't contain any 'unexpected' parameter keys. As I understand it, the default way would just create a member on the CO named color, and I don't see how to prevent arbitrary members using even custom validators. I'd happily entertain suggestions for doing so, thereby allowing us to use this default means.
Yes; what you can do is pass the command object as a parameter to the controller, and then the command will always be validated automatically.
Also, what you can do, is to make a filter or similar, so that you don't have to check for the hasErrors() each time, but handle all the cases in the same way (for example, by throwing an error, or returning with a specific response).
In an application we created, we had something like:
withValidCommand(cmd) {
// do work
}
Which worked pretty well. But maybe you can come up something even more elegant.
You should be doing this:
def someAction(SomeCommandObject co) {
if (!co.hasErrors()) {
someService.doWork(co)
}
}
By passing SomeCommandObject in as the argument grails will automatically populate it from params and validate. No need to do it manually.
I have been digging in the core of Laravel because I would like to understand how it works. But I come up with a method that I just cannot wrap my head around even after 3 days.
In start.php the app is binded to itself. So far so good. But when I check the $app->share method I am lost.
public function share(Closure $closure)
{
return function($container) use ($closure)
{
// We'll simply declare a static variable within the Closures and if
// it has not been set we'll execute the given Closure to resolve
// the value and return it back to the consumers of the method.
static $object;
if (is_null($object))
{
$object = $closure($container);
}
return $object;
};
}
This method returns an anonymous function which when executed returns an instance of the app. Do I see that right? Why is this? Why do you want to return a closure and not just the instance. This seems like a strange way, but I am quite sure that there is a reason ;) ??
UPDATE
The line in start.php:
$app['app'] = $app->share(function($app) { return $app; });
So I would think that $app['app'] is a closure object. However if I do get_class the class is Illuminate\Foundation\Application .
Furthermore there is also no way to execute it as $app'app' will not work obviously.
$app is no normal array, it is actually an instance of Illuminate\Foundation\Application1, an extension of Illuminate\Container\Container2, which implements ArrayAccess. But you know this already, as that's where the share() method lives.
The container binds keys to closures, when the keys are accessed the value is fetched from memory or, on first access, the bound closure is called and the resulting value is returned. When a key is set on the container it is wrapped in a closure unless it is already a closure.
This provides a consistent internal interface for the container, so that the code is not constantly type checking its contents. It will also only load the references you actually use are into memory - it is thought that the footprint of a closure is lighter than that of a fully loaded class instance. But once loaded, you get the benefit of working with the same instance for the rest of the request.
Why the app is not registered on the container using instance() I don't know though - perhaps it produces recursive references in trace and dump output.
With callback functions that are within the same class, I can't set the following.
private function check_valid_image
{
...
}
I can get it to work if I do the following.
function _check_valid_image
{
...
}
By placing an underscore in front of the method name, is that the same as placing the word private in front?
It's a convention used with the form validation class for callbacks. It also makes that method not callable via the URL segments.
That being said, it is not the equivalent of making a method private, which has implications in how code can be run outside of the class.
I did my research but haven't found any answers.
I'm using Html.RenderAction in a masterpage ( to render page header with links specific to user permissions ). Action is decorated with OutputCache, returns partial control and gets cached as expected.
When the event happens ( let's say permissions are changed ) I want to programmatically invalidate cached partial control.
I'm trying to use RemoveOutputCacheItem method. It takes a path as a parameter. I'm trying to set the path to the action used in Html.RenderAction. That doesn't invalidate the action.
How can I programmatically invalidate the action?
Thanks
The cache for child actions is stored in the OutputCacheAttribute.ChildActionCache property. The problem is that the API generating ids for child actions and storing them in this object is not public (WHY Microsoft??). So if you try to loop through the objects in this collection you will discover that it will also contain the cached value for your child action but you won't be able to identify it unless you reverse engineer the algorithm being used to generate keys which looks something like this (as seen with Reflector):
internal string GetChildActionUniqueId(ActionExecutingContext filterContext)
{
StringBuilder builder = new StringBuilder();
builder.Append("_MvcChildActionCache_");
builder.Append(filterContext.ActionDescriptor.UniqueId);
builder.Append(DescriptorUtil.CreateUniqueId(new object[] { this.VaryByCustom }));
if (!string.IsNullOrEmpty(this.VaryByCustom))
{
string varyByCustomString = filterContext.HttpContext.ApplicationInstance.GetVaryByCustomString(HttpContext.Current, this.VaryByCustom);
builder.Append(varyByCustomString);
}
builder.Append(GetUniqueIdFromActionParameters(filterContext, SplitVaryByParam(this.VaryByParam)));
using (SHA256 sha = SHA256.Create())
{
return Convert.ToBase64String(sha.ComputeHash(Encoding.UTF8.GetBytes(builder.ToString())));
}
}
So you could perform the following madness:
public ActionResult Invalidate()
{
OutputCacheAttribute.ChildActionCache = new MemoryCache("NewDefault");
return View();
}
which obviously will invalidate all cached child actions which might not be what you are looking for but I am afraid is the only way other than of course reverse engineering the key generation :-).
#Microsoft, please, I am begging you for ASP.NET MVC 4.0:
introduce the possibility to do donut caching in addition to donut hole caching
introduce the possibility to easily expire the result of a cached controller action (something more MVCish than Response.RemoveOutputCacheItem)
introduce the possibility to easily expire the result of a cached child action
if you do 1. then obviously introduce the possibility to expire the cached donut portion.
You might want to approach this a different way. You could create a custom AuthorizeAttribute -- it would simply allow everyone -- and add override the OnCacheValidation method to incorporate your logic. If the base OnCacheValidation returns HttpValidationStatus.Valid, then make your check to see if the state has changed and if so, return HttpValidationStatus.Invalid instead.
public class PermissionsChangeValidationAttribute : AuthorizeAttribute
{
public override OnAuthorization( AuthorizationContext filterContext )
{
base.OnAuthorization( filterContext );
}
public override HttpValidationStatus OnCacheAuthorization( HttpContextBase httpContext )
{
var status = base.OnCacheAuthorization( httpContext );
if (status == HttpValidationStatus.Valid)
{
... check if the permissions have changed somehow
if (changed)
{
status = HttpValidationStatus.Invalid;
}
}
return status;
}
}
Note that there are ways to pass additional data in the cache validation process if you need to track the previous state, but you'd have to replicate some code in the base class and add your own custom cache validation handler. You can mine some ideas on how to do this from my blog post on creating a custom authorize attribute: http://farm-fresh-code.blogspot.com/2011/03/revisiting-custom-authorization-in.html