Пользовательский связыватель моделей, который устраняет проблему с файлами cookie?
-
18-09-2019 - |
Вопрос
Я пытаюсь сделать следующее.
Используйте связку модели по умолчанию, чтобы связать объект из значений строки запроса.
Если это не удается, я пытаюсь связать объект на основе значений cookie.
Однако я использую аннотации данных для этого объекта, и у меня возникают следующие проблемы.
- Если параметры строки запроса отсутствуют, связыватель модели по умолчанию даже не регистрирует никаких ошибок проверки в обязательных полях.Очевидно, он даже не запускает эти валидаторы, если самого свойства нет в коллекции строк запроса.Как я могу изменить это поведение?Я бы хотел, чтобы обязательные поля были ошибками, если их нет в строке запроса.
- Если у меня есть ошибки проверки модели, я хотел бы загрузить модель из файла cookie, а затем повторно проверить объект.Я не уверен, как заставить связующее устройство модели проверить объект, который я заполнил сам.
Вот что у меня есть на данный момент.
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;
}
}
Любая помощь о том, как правильно это сделать, будет принята с благодарностью.
Решение
Ну, я решил это сам.Публикация решения здесь на случай, если у кого-то есть комментарии или он захочет его использовать.
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;
}
}
}
Не связан с StackOverflow