每个页面都有一个“ViewModel”(“Create.cshtml”和“Edit.cshtml”)?

发布于 2024-12-13 04:44:48 字数 2420 浏览 1 评论 0原文

问题

实际上有两个相关的问题:

  1. 我应该为每个页面创建一个ViewModel吗?
  2. 如果您在为两个页面(Create.cshtmlEdit.cshtml)创建单个 ViewModel 类时没有问题,我如何以不同的方式验证 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

感谢大家的帮助!

Questions

There are actually two related questions:

  1. Should I create a ViewModel for each page?
  2. If you do not have problems in creating a single ViewModel class for the two pages (Create.cshtml and Edit.cshtml) how can I validate the ViewModel in different ways (depending on the page that is being used)

Source

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");
    }
}

Note that if the user is editing an existing project, validation of the property name should not be done again.

ProjectController.cs > Edit method

[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);
}

Notes

If I create a ViewModel for each page, there is a duplication of code since pages have the same properties.

Add a property on the ViewModel indicating what page it is being displayed does not solve my problem as to instantiate the ViewModel, I use AutoMapper.

To validate the data, I use FluentValidator.

Thank you all for your help!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

木槿暧夏七纪年 2024-12-20 04:44:48

我的理解是 ViewModel 和 View 之间不存在 1:1 的相关性。通常,您会拥有一个不需要 ViewModel 与之配合的视图。

当且仅当您需要绝对并行并针对特定视图定制的模型时,您才需要创建 ViewModel。情况并非 100% 都是如此。

My understanding is that there isn't a 1:1 correlation between ViewModels and Views. Oftentimes you will have a View that will not require a ViewModel to go alongside with it.

You will want to create a ViewModel if and only if you need a Model absolutely paralleled and tailored to a specific View. This will not be the case 100% of the time.

感性 2024-12-20 04:44:48

当页面之间的功能/用例/验证不同时,我使用不同的模型。如果除了 ID 或类似内容之外完全相同,我会使用相同的模型,如果差异很小,也可以仅使用相同的视图。

由于您的验证不同,如果我这样做,我将创建两个不同的模型,以便我可以使用开箱即用的 DataAnnotations,并进行您的验证,尽管可能不需要。您还可以在编辑模型上具有名称的只读属性,因为它不再可编辑。

When the functionality / use case /validation is different between the pages I use different models. If its the exact same besides the presence of an ID or something similar I use the same model, and its also possible to just use the same view if the differences are pretty minor.

Since your validation is different, if I were doing it I would create two different models so that I could use the out of the box DataAnnotations, with your validation though it may not be required. You could also on the edit model have a readonly property for name since its not editable any longer.

酒浓于脸红 2024-12-20 04:44:48

对我来说,同一个对象每次都必须具有相同的验证,主要是为了确保对象的一致性,无论它是创建还是编辑的。

我认为您应该只创建一个验证,并编辑您的“存在”方法以验证它是新对象还是存储库中的当前对象。

For me the same object must have the same validation on every time, in main to ensure the consistence of the object, independently if it was created or edited.

i think that you should create only one validation, and edit your "exists" method to pass to verify if it is a new object or the current object in repository.

小矜持 2024-12-20 04:44:48

就我个人而言,我对 2 个视图模型没有问题,特别是如果(正如 Paul Tyng 建议的那样)您对编辑和创建场景常用的字段使用基类。

但是,如果您确实只想要一个视图模型,那么您需要:

  • 向视图模型添加一个标志并在验证器中使用 When() 方法。但请注意,这不会生成适当的仅客户端验证
  • ,定义第二个验证器并从控制器调用适当的验证器(即代替“自动”验证)

Personally, I don't have a problem with 2 view models, especially if (as Paul Tyng suggested) you use a base class for the fields that are common to edit and create scenarios.

However, if you really only want a single view model then you would either need to:

  • add a flag to the view model and use the When() method in your validator. Note though that this will not generate the appropriate client-side only validation
  • define a second validator and invoke the appropriate one from the controller (i.e. instead of the "automatic" validation)
[浮城] 2024-12-20 04:44:48

提供另一个视图 Edit.cshtml,它将允许用户编辑所选项目的数据。

  1. 创建另一个基于 ItemName 的视图 Query.cshtml 将允许用户查询 Inventory 表。

  2. 计算总利润(销售数量乘以(销售价格-购买成本)。显示总利润。

(奖励)创建另一个视图 Sell.cshtml,该视图将指示商品的销售情况。向 NumberSold 添加 1,并从 NumberInventory 中减去 1,以获得选定的记录。

Provide another view Edit.cshtml which will allow the user to edit the data for a selected item.

  1. Create another view Query.cshtml which based on the ItemName will allow the users to query the Inventory table.

  2. Perform the calculation for the total profit (numbersold times (saleprice-purchasecost). Display the total profit.

(BONUS) Create another view Sell.cshtml that will indicate the sale of an item. Adding one to NumberSold and subtract one from NumberInventory for the selected record.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文