Кажется, вы немного усложняете ситуацию.Я думаю, что вы хотите сделать, чтобы предотвратить привязку связывателя модели к свойствам, которые он не должен иметь, а также сохранить возможность проверки ModelState.IsValid
, когда свойства вашей модели не соответствуют требованиям их атрибутов проверки.
IMO лучший способ сделать это - использовать то, что я называю «строго типизированными фильтрами привязки».Сначала определите интерфейс только с теми свойствами, которые необходимо привязать для подшивки модели в вашей модели.
public interface INewBlogPost
{
string Title { get; set; }
string Body { get; set; }
}
Затем убедитесь, что ваша сущность наследуется от интерфейса фильтра привязки.
public class BlogPost : INewBlogPost
{
...
}
Затем измените метод действия, чтобы создать новый объект, и вручную вызовите подшивку модели, набрав ее на интерфейсе, который вы только что определили.
public ActionMethod NewBlogPost()
{
BlogPost newBlogPost = new BlogPost();
TryUpdateModel<INewBlogPost>(newBlogPost);
if (ModelState.IsValid)
{
...
}
}
Поскольку вы передали тип при вызове подшивки модели черезTryUpdateModel
вы явно указали связующему модели, к какому типу привязываться.Это означает, что связыватель модели будет иметь доступ только к свойствам, перечисленным в интерфейсе.Теперь, когда вы передаете модель в метод для привязки, она должна иметь тип INewBlogPost
.Поскольку ваша сущность наследуется от интерфейса фильтра привязки, ее экземпляр будет удовлетворять этому требованию.Механизм связывания модели с радостью свяжется со свойствами интерфейса, совершенно не обращая внимания на любые другие свойства, которые может иметь объект вашей модели.
Подробнее см. в этом блоге .
Помимо
Иногда бывает легко столкнуться с неоднозначностью методов действия, когда у вас есть два метода действия с одинаковым именем;один для POST и один для GET, например:
[HttpGet]
public ActionResult NewBlogPost()
{
return View();
}
[HttpPost]
public ActionResult NewBlogPost()
{
BlogPost newBlogPost = new BlogPost();
TryUpdateModel<INewBlogPost>(newBlogPost);
if (ModelState.IsValid) { ... }
}
Простой способ исправить это - изменить метод действия POST, чтобы он выглядел следующим образом:
[HttpPost]
public ActionResult NewBlogPost(FormCollection formCollection)
{
BlogPost newBlogPost = new BlogPost();
TryUpdateModel<INewBlogPost>(newBlogPost, formCollection);
if (ModelState.IsValid) { ... }
}
Связыватель модели MVCзнает, как связать коллекцию форм запроса с аргументом типа FormCollection
, поэтому он заполнит это просто отлично.Поскольку ваше действие POST теперь принимает аргумент, он больше не является двусмысленным с вашим методом GET.Вы можете передать эту форму FormCollection в TryUpdateModel
, чтобы использовать ее в качестве источника привязки, если хотите, но вам это не нужно, так как она все равно будет использоваться по умолчанию для коллекции форм запроса.Но так как вы передаете его внутрь, вы также можете использовать его:)