Проверка модели ASP.NET MVC нарушает правило MVC? - PullRequest
6 голосов
/ 18 мая 2011

используя ASP.NET MVC, у меня есть Модель, к которой я прикрепляю атрибуты, чтобы я мог использовать проверку границ модели MVC, но для это не нарушает правила MVC где вы помещаете элементы, принадлежащие представлению, в модель? Я надеюсь, что я не пытаюсь быть умным, но мне любопытно узнать мнение других.

public class Payments
{
    [DataType(DataType.Text)]
    [DisplayFormat(NullDisplayText="")]
    [Display(Name="Payment Id")]
    [Required(ErrorMessage="Required")]
    public int PaymentId { get; set; } //todo: make this into a dropdown

    [DataType(DataType.Text)]
    [Display(Name="Bill Name")]
    [Required(ErrorMessage = "Required")]
    public string PaymentName { get; set; }

    [DataType(DataType.Date)]
    [Display(Name="Date to Post Payment")]
    [Required(ErrorMessage = "Required")]
    public DateTime PaymentDate { get; set; }

    [DataType(DataType.Currency)]
    [Range(0, 922337203685477.5807)]
    [Required(ErrorMessage = "Required")]
    public double PaymentAmount { get; set; }
}

Ответы [ 3 ]

10 голосов
/ 18 мая 2011

Вы можете, но не обязаны, добавлять эти атрибуты проверки в вашу модель.

Но лучше использовать ViewModel:

public class PaymentsViewModel
{
    [DataType(DataType.Text)]
    [DisplayFormat(NullDisplayText="")]
    [Display(Name="Payment Id")]
    [Required(ErrorMessage="Required")]
    public int PaymentId { get; set; } //todo: make this into a dropdown

    [DataType(DataType.Text)]
    [Display(Name="Bill Name")]
    [Required(ErrorMessage = "Required")]
    public string PaymentName { get; set; }

    [DataType(DataType.Date)]
    [Display(Name="Date to Post Payment")]
    [Required(ErrorMessage = "Required")]
    public DateTime PaymentDate { get; set; }

    [DataType(DataType.Currency)]
    [Range(0, 922337203685477.5807)]
    [Required(ErrorMessage = "Required")]
    public double PaymentAmount { get; set; }
}

И в вашем представлении вместо:

@model YourProject.Models.Payments

вы используете:

@model YourProject.Models.PaymentsViewModel

для проверки.

10 голосов
/ 18 мая 2011

Да. Вот почему вы должны использовать ViewModels.

1 голос
/ 18 мая 2011

Нарушает ли это MVC в строгом смысле, да, наверное.Есть ли случаи, когда нарушать это не вредно?Конечно.Тем не менее, существуют механизмы, которые могут помочь вам и разделить проблемы.

Вы можете использовать ваши постоянные доменные объекты в представлениях и проверять их, но когда ваше представление становится сложным, ViewModels становятся необходимостью.Для мертвых простых доменных моделей или представлений только для просмотра (не редактирует / создает) я иногда немного выдумываю и отправляю их в представление как часть составного объекта:

class MyViewModel
{
    public MyDomainModel DomainObj;
    public int OtherViewInfo;
}

Однако для созданияи редактировать сценарии, ViewModels намного лучше.Они позволяют вам полностью контролировать данные, отправляемые в представление и из представления.

Если вы используете EF 4.1 и CodeFirst, то да, в итоге вы получите некоторое дублированиеатрибутов и свойств между доменом и ViewModel.Это неизбежно, но дает вам гибкость в выполнении различных проверок, специфичных для представления.

Я считаю полезным иметь один дополнительный уровень защиты в контроллере при фактическом сохранении объекта домена на случай, если я пропустил некоторыепроверка в представлении:

public class MyController : Controller
{
    [HttpPost]
    public ActionResult Edit(int id, MyViewModel model)
    {
        try
        {
            ...Do stuff, check ModelState.IsValid...
            _context.SaveChanges()
        }
        catch (DbEntityValidationException dbEx)
        {
            // Catch any validation errors on the domain that weren't duplicated
            // in the viewmodel
            ModelState.AddModelError("Form", dbEx);
        }

        return View(model);
    }
}

Следующий вопрос, который нужно задать, - это как вы сопоставляете модель домена с моделью представления.Существует целый ряд стратегий и инструментов - AutoMapper и ValueInjecter (да, написано неправильно).Лично я использую ValueInjecter, хотя, если вы настроите слой отображения, вы можете попробовать оба.Я обнаружил, что ни один из них не будет работать в 100% случаев, или, по крайней мере, я мог бы понять, как делать то, что мне было нужно, но картографический сервис облегчает определение пользовательских карт слева направо.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...