ASP.NET MVC - альтернатива для [Bind (Exclude = Id)]

Есть ли альтернатива для [Bind(Exclude = "Id")] (Связанный вопрос)?

Могу ли я написать скоросшиватель моделей?


person Rookian    schedule 07.01.2011    source источник


Ответы (5)


Да, есть: это называется моделями просмотра. Модели представления - это классы, специально предназначенные для конкретных потребностей данного представления.

Так что вместо:

public ActionResult Index([Bind(Exclude = "Id")] SomeDomainModel model)

использовать:

public ActionResult Index(SomeViewModel viewModel)

где модель представления содержит только те свойства, которые необходимо связать. Затем вы можете сопоставить модель вида и модель. Это сопоставление можно упростить с помощью AutoMapper.

В качестве наилучшей практики я бы порекомендовал вам всегда использовать модели представления в представление и из представления.

person Darin Dimitrov    schedule 08.01.2011
comment
+1 Это лучшее описание модели ViewModel vs Business, которое я когда-либо видел. Я никогда не думал об этом с точки зрения безопасности. Но это причина использовать модель представления, по крайней мере, для http. - person jgauffin; 08.01.2011
comment
поэтому мне нужны отдельные модели представления для обновления и создания сценариев, не так ли? - person Rookian; 08.01.2011
comment
@Rookian, да, это хорошая практика - иметь отдельные модели просмотра. - person Darin Dimitrov; 08.01.2011
comment
@Darin: поэтому, когда у вас есть большой, сложный граф объектов предметной области со многими свойствами (и отношениями, правилами проверки и т. Д.), Которые необходимо представить в форме, вы переопределяете все соответствующие свойства в своих моделях представления, вручную скопировать все свойства между ними и т.д.? Похоже, это приведет к большому количеству дублирования, жестких зависимостей и избыточного кода, поэтому я избегал этого как чумы - хотя это кажется правильным подходом, на практике я не понимаю, как вы все обойдете неловкое дублирование и повторение .. ?? - person mindplay.dk; 27.07.2011
comment
@ mindplay.dk, все, что нужно, я вложил в модель представления. Если моя исходная модель предметной области имеет сложный граф свойств, я мог бы его сгладить. Но я снова включаю в представление только то, что мне нужно показать / отредактировать. Если это просто для сохранения некоторых данных в скрытых полях (эмуляция ViewState sorta), я не включаю эти свойства в модель представления. Я включаю только идентификатор, который позволит мне получить эту информацию оттуда, где она хранится. Что касается ручного копирования, то нет, я ничего не делаю вручную, я использую AutoMapper, который делает это за меня. - person Darin Dimitrov; 27.07.2011
comment
@Darin: но вы дублируете все те свойства из вашей модели предметной области, которые требуются в представлении, верно? Что насчет аннотаций проверки, вы дублируете их все или у вас есть только аннотации проверки на моделях представления? (Спасибо, что поделился!) - person mindplay.dk; 28.07.2011
comment
@ mindplay.dk, я дублирую только то, что мне нужно на мой взгляд. Что касается проверки, я выполняю проверку моделей представления. Для этого я использую FluentValidation.NET. Не беспокойтесь о DataAnnotations. - person Darin Dimitrov; 28.07.2011
comment
В моем случае я был вынужден использовать ViewModel, потому что мои классы были классами NHibernate, поэтому, когда он пытается сериализовать ленивое свойство, он терпит неудачу ... - person Kat Lim Ruiz; 06.08.2014
comment
@DarinDimitrov, какой синтаксис использовать вместе в одной модели просмотра? - person Ehsan Sajjad; 20.02.2018

Вы можете исключить свойства напрямую с помощью атрибута, используя;

[BindNever]
person PaulB    schedule 24.01.2018

Очень простое решение, в котором я разобрался.

public ActionResult Edit(Person person)
{
    ModelState.Remove("Id"); // This will remove the key 

    if (ModelState.IsValid)
       {
           //Save Changes;
       }
    }
}
person Desmond    schedule 01.11.2012

В дополнение к существующим ответам C # 6 позволяет более безопасным способом исключить свойство:

public ActionResult Edit(Person person)
{
    ModelState.Remove(nameof(Person.Id));

    if (ModelState.IsValid)
       {
           //Save Changes;
       }
    }
}

or

public ActionResult Index([Bind(Exclude = nameof(SomeDomainModel.Id))] SomeDomainModel model)
person Memet Olsen    schedule 10.02.2016
comment
Мне нравится этот ответ, но я все же считаю, что вам следует использовать ViewModels и POCO's в отношении шаблона дизайна и SoC. - person Chef_Code; 10.01.2017
comment
как бы вы это сделали, если бы хотели исключить двоих из них? - person John Lord; 15.10.2020

Как заявил Десмонд, я считаю, что remove очень прост в использовании, также я сделал простое расширение, которое может пригодиться для игнорирования нескольких реквизитов ...

    /// <summary>
    /// Excludes the list of model properties from model validation.
    /// </summary>
    /// <param name="ModelState">The model state dictionary which holds the state of model data being interpreted.</param>
    /// <param name="modelProperties">A string array of delimited string property names of the model to be excluded from the model state validation.</param>
    public static void Remove(this ModelStateDictionary ModelState, params string[] modelProperties)
    {
        foreach (var prop in modelProperties)
            ModelState.Remove(prop);
    }

Вы можете использовать это в своем методе действий следующим образом:

    ModelState.Remove(nameof(obj.ID), nameof(obj.Prop2), nameof(obj.Prop3), nameof(obj.Etc));
person Vedran Mandić    schedule 12.06.2014