Как вы исключаете свойства привязки при вызове UpdateModel()?
У меня есть модель представления, отправленная в действие редактирования моего контроллера. ViewModel содержит ссылки на EntityObjects. (да, я в порядке с ним и не нужно дублировать все свойства сущностей в viewmodel).
Я создаю экземпляр модели представления, а затем вызываю UpdateModel. Я получаю сообщение об ошибке, что свойство имеет значение "null", что отлично, поскольку это родственная модель. Я пытаюсь исключить свойство из привязки во время привязки модели. При отладке я вижу в объекте, где привязка модели пытается установить значение свойства null.
Вот мое действие для редактирования:
var model = new SimplifiedCompanyViewModel(id);
var excludeProperties = new string[] {
"Entity.RetainedEarningsAccount.AccountNo"
,"Property.DiscountEarnedAccount.ExpenseCodeValue"
,"Entity.EntityAlternate.EntityID"
,"Property.BankAccount.BankAccountID"
,"Entity.PLSummaryAccount.AccountNo"
,"Property.RefundBank.BankAccountID"
,"Company.Transmitter.TCC"
};
try
{
UpdateModel<SimplifiedCompanyViewModel>(model, String.Empty, null, excludeProperties);
if (ModelState.IsValid)
{
//db.SaveChanges();
}
return RedirectToAction("Index");
}
catch
{
return View(model);
}
Я рассмотрел несколько других вопросов, касающихся указания "префикса", но я не думаю, что это проблема, поскольку я говорю ему привязывать к экземпляру viewmodel не только объект сущности.
Я правильно ли исключаю свойства? Странная вещь, похоже, происходит только на этом предмете. Я подозреваю, что это может быть проблемой с тем фактом, что на самом деле нет банка возврата, связанного с моей организацией. Но у меня есть другие связанные элементы, которые не существуют и не видят той же проблемы.
Больше информации... поскольку мне говорят, что модель не разработана хорошо.
Компания связана с Банком. В представлении "Компания" отображается связанный с этим BankAccount.BankAccountId, и есть скрытое поле с BankAccount.Key. Я использую функцию автозаполнения jQueryUI, чтобы предоставить раскрывающийся список банковских счетов, отображающий BankAccount.BankAccountId, и когда один из них выбран, код jQuery изменяет скрытое поле, чтобы иметь правильное значение Key. Итак, когда это опубликовано, я не хочу, чтобы текущие банковские счета BankAccountID были изменены, поэтому я хочу, чтобы он пропускал привязку этого поля.
Если я исключу BankAccountId в модели, то в представлении редактирования BankAccount пользователь никогда не сможет изменить BankAccountId, поскольку он не будет связан. Я не уверен, как это указывает на плохой дизайн модели.
Ответы
Ответ 1
Другой вариант здесь просто не включает этот атрибут в ваш взгляд, и он не будет связан. Да, вы все еще открыты для моделирования инъекций, если кто-то создает ее на странице, но это еще одна альтернатива. Шаблоны по умолчанию в MVC создадут ваш редактор и т.д. В качестве отдельных элементов, поэтому вы можете просто удалить их. Это не позволяет использовать редактор строк в редакторе EditorForModel, но шаблоны не генерируют его таким образом.
EDIT (добавление выше комментария)
DRY обычно применяется к логике, а не для просмотра моделей. Один вид = одна модель представления. Используйте automapper, чтобы легко отображать между ними. У Jimmy Bogard есть отличный атрибут для этого, что делает его почти автоматическим - то есть вы создаете модель представления, загружаете, например, объект Customer и возвращаете его в методе действий. Атрибут AutpMap затем преобразует его в ViewModel. См. lostechies.com/jimmybogard/2009/06/30/how-we-do-mvc-view-models
Ответ 2
Используйте свойство Exclude
Bind
:
[Bind(Exclude="Id,SomeOtherProperty")]
public class SimplifiedCompanyViewModel
{
public int Id { get; set; }
// ...
}
Это часть пространства имен System.Web.Mvc
. Для исключения при связывании он должен иметь список имен свойств, разделенных запятыми.
Также вы должны использовать TryUpdateModel вместо UpdateModel. Вы также можете просто использовать привязку модели модели по умолчанию, передав ее в качестве аргумента конструктору:
public ActionResult Create([Bind(Exclude="Id")]SimplifiedCompanyViewModel model)
{
// ...
}
Ответ 3
Очень простое решение, которое я выяснил.
try
{
UpdateModel<SimplifiedCompanyViewModel>(model, String.Empty, null, excludeProperties);
ModelState.Remove("Entity.RetainedEarningsAccount.AccountNo");
ModelState.Remove("Property.DiscountEarnedAccount.ExpenseCodeValue");
ModelState.Remove("Entity.EntityAlternate.EntityID");
ModelState.Remove("Property.BankAccount.BankAccountID");
ModelState.Remove("Entity.PLSummaryAccount.AccountNo");
ModelState.Remove("Property.RefundBank.BankAccountID");
ModelState.Remove("ompany.Transmitter.TCC");
if (ModelState.IsValid)
{
//db.SaveChanges();
}
return RedirectToAction("Index");
}
catch
{
return View(model);
}
Ответ 4
Попробуйте атрибут Exclude.
Я признаю, что я никогда не использовал его.
[Exclude]
public Entity Name {get; set;}