`ViewModel` для каждой страницы (` Create.cshtml` и `Edit.cshtml`)? - PullRequest
3 голосов
/ 01 ноября 2011

Вопросы

На самом деле есть два связанных вопроса:

  1. Должен ли я создать ViewModel для каждой страницы?
  2. Если у вас нет проблем при создании одного класса ViewModel для двух страниц (Create.cshtml и Edit.cshtml), как я могу проверить ViewModel по-разному (в зависимости от используемой страницы)

Источник

ViewModel

public class ProjectViewModel
{
    public string Name { get; set; }
    public string Url { get; set; }
    public string Description { get; set; }
}

Edit.cshtml

@using BindSolution.ViewModel.Project
@model ProjectViewModel
@{
    ViewBag.Title = Model.Name;
}

@Html.EditorForModel()

Create.cshtml

@using BindSolution.ViewModel.Project
@model ProjectViewModel
@{
    ViewBag.Title = "New Project";
}

@Html.EditorForModel()

ProjectValidator.cs

public class ProjectValidator : AbstractValidator<ProjectViewModel>
{
    private readonly IProjectService _projectService;

    public ProjectValidator(IProjectService projectService)
    {
        _projectService = projectService;

        RuleFor(p => p.Name)
           .NotEmpty().WithMessage("required field")

           /*The validation should be made only if the page is Create.cshtml. That is, if you are creating a new project.*/
           .When(p => p.??) //Problem Here!!

           .Must(n => !_projectService.Exist(n)).WithMessage("name already exists");

        RuleFor(p => p.Url)
            .NotEmpty().WithMessage("required field");
    }
}

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

ProjectController.cs> Метод редактирования

[HttpPost]
public ActionResult Edit(Guid projectID, ProjectViewModel model)
{
    var project = _projectService.Repository.Get(projectID);

    if (ModelState.IsValid && TryUpdateModel(project))
    {
        _projectService.Repository.Attach(project);
        if (_projectImageWrap.Create(project) && _projectService.Repository.Save() > 0)
            return AjaxRedirect("Index");
    }

    return View(model);
}

Примечания

Если я создаю ViewModel для каждой страницы, происходит дублирование кода, поскольку страницы имеют одинаковые свойства.

Добавление свойства в ViewModel, указывающее, какая страница отображается, не решает мою проблему, так как для создания экземпляра ViewModel я использую AutoMapper.

Для проверки данных я использую FluentValidator .

Спасибо всем за помощь!

Ответы [ 4 ]

0 голосов
/ 20 декабря 2012

Лично у меня нет проблем с двумя моделями представления, особенно если (как предложил Пол Тайнг) вы используете базовый класс для полей, которые являются общими для редактирования и создания сценариев.

Однако, если вы действительно хотите использовать только одну модель представления, вам потребуется:

  • добавьте флаг к модели представления и используйте метод When () в вашем валидаторе. Обратите внимание, что это не будет генерировать соответствующую проверку только на стороне клиента
  • определить второй валидатор и вызвать соответствующий из контроллера (т. Е. Вместо «автоматической» валидации)
0 голосов
/ 01 ноября 2011

Когда функциональность / вариант использования / валидация отличаются на разных страницах, я использую разные модели.Если он точно такой же, кроме наличия идентификатора или чего-то подобного, я использую ту же модель, и также возможно использовать тот же самый вид, если различия довольно незначительны.

Поскольку ваша проверка отличается, еслиЯ делал это, я создавал две разные модели, чтобы я мог использовать готовые DataAnnotations с вашей проверкой, хотя это может и не потребоваться.Вы также можете использовать в редактируемой модели свойство только для чтения для name, поскольку оно больше не редактируется.

0 голосов
/ 01 ноября 2011

Для меня один и тот же объект должен иметь одинаковую проверку каждый раз, в основном, чтобы обеспечить согласованность объекта, независимо от того, был ли он создан или отредактирован.

Я думаю, что вы должны создать только одну проверкуи отредактируйте свой метод «существует», чтобы передать его, чтобы убедиться, что это новый объект или текущий объект в хранилище.

0 голосов
/ 01 ноября 2011

Насколько я понимаю, между ViewModels и Views нет корреляции 1: 1.Часто у вас будет View, для которого не требуется ViewModel, чтобы идти вместе с ним.

Вы захотите создать ViewModel тогда и только тогда, когда вам нужна модель, абсолютно параллельная и адаптированная к конкретному представлению.Это не будет иметь место в 100% случаев.

...