Custom Model-Binder that pulls from a cookie problem?
I am trying to do the following.
Use the default model binder to bind an object from query string values.
If that fails, I then try and bind the object from cookie values.However I am using dataannotations on this object and I am having the following problems.
- If there are no querystring parameters the default model binder doesn't even register any validation errors on required fields. It apparently doesn't even fire these validators if the p开发者_C百科roperty itself is not in the query string collection. How can I change this behavior? I would like the required fields to be errors if they aren't in the query string.
- If I do have model validation errors, I would like to then load the model from the cookie and then revalidate the object. I am not sure how to get the model binder to validate an object I have populated myself.
Here is what I have so far.
public class MyCarBinder : DefaultModelBinder
{
public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
var myCar = base.BindModel(controllerContext, bindingContext);
if (!bindingContext.ModelState.IsValid)
{
myCar = MyCar.LoadFromCookie();
// Not sure what to do to revalidate
}
return myCar;
}
}
Any help on how to properly do this would be greatly appreciated.
Well, I solved it myself. Posting the solution here in case anyone has a comments or might like to use it.
public class MyCarBinder : DefaultModelBinder
{
public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
var queryStringBindingContext = new ModelBindingContext()
{
FallbackToEmptyPrefix = bindingContext.FallbackToEmptyPrefix,
ModelMetadata = bindingContext.ModelMetadata,
ModelName = bindingContext.ModelName,
PropertyFilter = bindingContext.PropertyFilter,
ValueProvider = new QueryStringValueProvider(controllerContext),
ModelState = new ModelStateDictionary()
};
var myCar = base.BindModel(controllerContext, queryStringBindingContext);
if (queryStringBindingContext.ModelState.IsValid)
return myCar;
// try to bind from cookie if query string is invalid
var cookieHelper = new Helpers.ControllerContextCookieHelper(controllerContext);
NameValueCollection nvc = cookieHelper.GetCookies(Helpers.CookieName.MyCar);
if (nvc == null)
{
bindingContext.ModelState.Merge(queryStringBindingContext.ModelState);
return myCar;
}
var cookieBindingContext = new ModelBindingContext()
{
FallbackToEmptyPrefix = bindingContext.FallbackToEmptyPrefix,
ModelMetadata = bindingContext.ModelMetadata,
ModelName = bindingContext.ModelName,
PropertyFilter = bindingContext.PropertyFilter,
ValueProvider = new NameValueCollectionValueProvider(nvc, CultureInfo.InvariantCulture),
ModelState = new ModelStateDictionary()
};
var myCarFromCookie = base.BindModel(controllerContext, cookieBindingContext);
if (cookieBindingContext.ModelState.IsValid)
{
MyCar temp = myCarFromCookie as MyCar;
if (temp != null)
temp.FromCookie = true;
return myCarFromCookie;
}
else
{
bindingContext.ModelState.Merge(queryStringBindingContext.ModelState);
return myCar;
}
}
}
精彩评论