Personalizzato Model Binder che tira da un problema biscotto?
-
18-09-2019 - |
Domanda
che sto cercando di fare quanto segue.
Utilizza il legante modello predefinito per associare un oggetto da valori di stringa di query.
Se non funziona, allora provo e associare l'oggetto da valori dei cookie.
Comunque io sto usando dataannotations su questo oggetto e sto avendo i seguenti problemi.
- Se non ci sono parametri querystring il legante modello predefinito non ha nemmeno registrare eventuali errori di validazione su campi richiesti. E a quanto pare non ha nemmeno sparare questi validatori se la proprietà stessa non è presente nella collezione stringa di query. Come posso cambiare questo comportamento? Vorrei che i campi richiesti per essere errori se non sono nella stringa di query.
- Se io ho errori di convalida del modello, vorrei quindi caricare il modello dal cookie e quindi rinnovare l'oggetto. Io non sono sicuro di come ottenere il modello legante per convalidare un oggetto mi sono popolate.
Ecco quello che ho finora.
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;
}
}
Qualsiasi aiuto su come fare correttamente questo sarebbe molto apprezzato.
Soluzione
Bene, ho risolto io stesso. Distacco la soluzione qui nel caso qualcuno ha un commenti o potrebbe piacere usarlo.
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;
}
}
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow