GVKun编程网logo

asp.net-mvc – Fluent Validation,Domain和ViewModels(fluent uninitialized flow field)

7

针对asp.net-mvc–FluentValidation,Domain和ViewModels和fluentuninitializedflowfield这两个问题,本篇文章进行了详细的解答,同时本文

针对asp.net-mvc – Fluent Validation,Domain和ViewModelsfluent uninitialized flow field这两个问题,本篇文章进行了详细的解答,同时本文还将给你拓展.net – MVC,ViewModels和Validation、ASP.Net MVC C#另一个viewmodel中的两个viewmodel – 如何在视图中引用、ASP.NET MVC – 用于编辑的ViewModels、ASP.NET MVC5验证系列之Fluent Validation等相关知识,希望可以帮助到你。

本文目录一览:

asp.net-mvc – Fluent Validation,Domain和ViewModels(fluent uninitialized flow field)

asp.net-mvc – Fluent Validation,Domain和ViewModels(fluent uninitialized flow field)

我一直在用asp.net mvc,nhibernate和ddd概念开发一个web应用程序.

我已经为我的域类开发了Fluent验证的验证,它工作正常.那么,现在,我需要一个viewmodel来编辑View中的实体,所以我的问题是,我是否需要创建另一个验证类来验证我的viewmodel?或者我应该怎么做以解决这种情况?

我问它是因为我不想打破DRY(不要重复自己)concetp.

谢谢!

解决方法

域级验证和视图模型验证是完全不同的(虽然它们可以有很多重叠).

例如,在数据库中将某个字段设置为null可能是完全允许的,但需要在某些webforms上输入它.在这种情况下,您将在模型验证中检查null.

多个客户端应用程序共享相同的域控制器(例如通过WCF),但拥有不同的应用程序验证逻辑也是很正常的.

如果你在视图模型中使用DataAnnotations,你可以免费获得客户端javascript验证,所以作为一般规则,我总是从我的Domain对象中有一个单独的viewmodel,即使它是1:1映射 – 我只是使用AutoMapper来在他们之间翻译.除了获得客户端验证之外,它还减少了域验证中的混乱.

.net – MVC,ViewModels和Validation

.net – MVC,ViewModels和Validation

我正在使用POCO创建一个带有EF4的MVC3应用程序.我已经为我的EF实体添加了验证属性.现在,当我构建视图时,我想使用视图模型(也许使用 AutoMapper来填充它们).

我遇到的问题是我必须在我的视图模型上重新定义我的验证属性,这违反了DRY主体.例如,如果我决定更改字段的大小,我必须更改POCO和使用它的任何视图模型的MaxLength属性.

是否有一些棘手的方法可以将验证规则从我的POCO映射到我的视图模型?

解决方法

我也很挣扎,我同意它违反DRY.我最近发布了一个关于这个 Here的问题并得到了相当多的阻力.

在任何现实世界的应用程序中,您都无法获得完美的DRY.有时你会因违反原则而不是盲目地坚持下去而获得更多好处.

编辑:

人们也可能认为DRY可能违反单一责任原则(SRP).通过重用类似的代码,您现在正在使代码执行多个操作.如果您认为数据模型和视图模型具有不同的目的,从而具有不同的职责……将它们组合到单个模型中会违反SRP.也就是说,通过使您的数据模型也成为一个视图模型,这是两个不同的职责.

现在,人们可以想到在这方面可以尝试和协调SRP与DRY的多种方法,但在某些时候你必须权衡成本的好处.

ASP.Net MVC C#另一个viewmodel中的两个viewmodel – 如何在视图中引用

ASP.Net MVC C#另一个viewmodel中的两个viewmodel – 如何在视图中引用

我试图通过使用viewmodels来遵循建议的最佳实践.

在我的论坛应用程序中,我想发布一个帖子列表,并在屏幕底部添加一个文本框,以便发布回复.

所以在我看来,我需要一个viewmodel用于Posts列表,一个viewmodel用于发布Reply(TopicId和Content).

因此,我认为我需要在第三个viewmodel中将这两个viewmodel组合在一起,并在我的View中迭代viewmodel的Posts部分,然后在底部创建一个表单,其中我有viewmodel的Reply部分 – 并且Postback仅将Replyviewmodel发送到控制器.

我的viewmodel是:

public class Postviewmodel
{
    public int PostId { get; set; }
    public string Title { get; set; }
    public string Description { get; set; }
    public string Author { get; set; }
    public DateTime DateOfTopic { get; set; }
}

public class Replyviewmodel
{
    public int TopicId { get; set; }
    public string Content { get; set; }
}

public class PostListAndReplyVM
{
    public List<Postviewmodel> Postviewmodel { get; set; }
    public Replyviewmodel Replyviewmodel { get; set; }
}

在我的控制器中,我填充Postviewmodel,然后创建一个空的Replyviewmodel,然后将它们组合在PostListAndReplyVM中:

//
    // GET: /Post/List/5
    public ActionResult List(int id = 0)
    {
        // Populate Postviewmodel

        var post = db.Posts.Include(x => x.Topic)
              .Select(p => new Postviewmodel
              {
                  PostId = p.TopicId,Title = p.Title,Description = p.Content,DateOfTopic = p.DateOfPost,Author = p.Author
              }
             ).ToList();

        // Populate empty Replyviewmodel

        Replyviewmodel prvm = new Replyviewmodel();
        prvm.Content = "";
        prvm.TopicId = id;

        // Combine two viewmodels into a third,to send to the controller

        PostListAndReplyVM pvm = new PostListAndReplyVM();
        pvm.Replyviewmodel = prvm;
        pvm.Postviewmodel = post;

        // Return combined viewmodel to the view

        return View(pvm);
    }

然后在我看来,我有:

@model IEnumerable<centreforum.Models.PostListAndReplyVM>

<table>
<tr>
    <th>
        @Html.displayNameFor(model => model.PostId)
    </th>
....
....
@foreach (var item in Model) {
<tr>
    <td>
        @Html.displayFor(modelItem => item.PostId)
    </td>

如何引用发布到视图的PostListAndReplyVM中的两个单独的viewmodel.例如.如果我认为它应该是这样的:

@Html.displayFor(modelItem => itemitem.Postviewmodel.PostId)

…但是这给出了错误:

‘centreforum.Models.PostListAndReplyVM’不包含’PostId’的定义,也没有扩展方法’PostId’接受’centreforum.Models.PostListAndReplyVM’类型的第一个参数’

对于列表部分:

@foreach (var item in Model.Postviewmodel)

…给出错误:

‘System.Collections.Generic.IEnumerable’不包含’Postviewmodel’的定义,并且没有扩展方法’Postviewmodel’接受类型’System.Collections.Generic.IEnumerable’的第一个参数可以找到

我确定我错过了一些简单的东西 – 感谢您的帮助,

标记

解决方法

我认为你的视图出错,你在控制器上返回一个PostListAndReplyVM,你的视图引用了一个IEnumerable的PostListAndReplyVM.

您必须在视图中更改声明的模型

@model centreforum.Models.PostListAndReplyVM

希望它有所帮助

ASP.NET MVC – 用于编辑的ViewModels

ASP.NET MVC – 用于编辑的ViewModels

为MVC应用程序同时查看和编辑模型通常是一种好习惯吗?意思是,我不希望视图模型上的验证属性,因为它基本上是只读的.

解决方法

我通常为每个视图创建一个新的视图模型.我发现viewmodel在实践中的重用程度非常低,并试图使它们超级通用并不能很好地工作并导致一些奇怪的情况.

当我第一次开始创建viewmodel时,我会创建这些非常抽象的viewmodel,我会尝试强制执行一堆业务逻辑但后来我意识到在大多数情况下,我试图在每种情况下显示的数据完全不同并且重用没有用.所以我刚开始将我的viewmodel分解成一次使用的非常小的部分.到目前为止,这一点运作良好.

我的大部分业务逻辑现在都试图保留在模型中而不是视图模型中.我的情况我的模型是一个实体框架模型,我将业务逻辑放在我的数据库对象之外的部分类中.

ASP.NET MVC5验证系列之Fluent Validation

ASP.NET MVC5验证系列之Fluent Validation

前面两篇文章学习到了,服务端验证,和客户端的验证,但大家有没有发现,这两种验证各自都有弊端,服务器端的验证,验证的逻辑和代码的逻辑混合在一起了,如果代码量很大的话,以后维护扩展起来,就不是很方便。而客户端的验证,必须要启用客户端验证,也就是在配置文件中配置相应的节点,并且还要引入Jquery插件。如果人为的在浏览器上,禁用了js脚本,那么客户端验证就不起作用了,所以在这里,我将继续学习另外一个验证,也就是Fluent Validation。

Fluent Validation是一个开源的.NET类库,它使用Fluent接口和lambda表达式,来为实体做验证。Fluent Validation是专门为实体做验证使用的。它的优点是:把验证逻辑和你代码的业务逻辑分别开了。这就是AOP的思想。就是横切关注点。你只需要关注某一个模块。这样就保证了代码的纯洁度。

Fluent Validation开源地址:https://github.com/JeremySkinner/fluentvalidation 

例句:
Aspect-oriented program is a new software development paradigm that enables modular implementation of cross-cutting concerns,and poses difficulties for slicing of aspect-oriented programs.
面向方面程序设计作为一种新的软件开发范型,能够实现横切关注点的模块化,其特有的语言元素和功能为切片增加了难度。
好了,废话太多,直接进入正题,
首先我们新建一个空白的MVC项目:在Model文件夹下新建一个类Customer: 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace Server_Side_Validation_IN_MVC.Models
{
 public class Customer
 {
  public string Name { get; set; }
  public string Email { get; set; }
 }
}

然后新建一个文件夹Validator,在里面添加一个类CustomerValidator 

既然是要使用Fluent Validation,那么就是要引用它的类库了。 

CustomerValidator类中,继承AbstractValidator抽象类,(PS:这里和EF中的Fluent API类似,EF中是继承EntityTypeConfiguration类) 

using FluentValidation;
using Server_Side_Validation_IN_MVC.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace Server_Side_Validation_IN_MVC.Validator
{
 public class CustomerValidator:AbstractValidator<Customer>
 {
  public CustomerValidator()
  {
   RuleFor(s => s.Name).NotEmpty().WithMessage("名字不能为空");
   RuleFor(s => s.Email).NotEmpty().WithMessage("电子邮件不能为空");
   RuleFor(s => s.Email).EmailAddress().WithMessage("电子邮件格式不合法");
  }
 }
}

控制器中的代码: 

using FluentValidation.Results;
using Server_Side_Validation_IN_MVC.Models;
using Server_Side_Validation_IN_MVC.Validator;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace Server_Side_Validation_IN_MVC.Controllers
{
 public class CustomerController : Controller
 {
  // GET: Customer
  public ActionResult Index()
  {
   return View();
  }

  [HttpPost]
  public ActionResult Index(Customer model)
  {
   CustomerValidator validator = new CustomerValidator();
   ValidationResult result = validator.Validate(model);

   if (result.IsValid)
   {
    ViewBag.Name = model.Name;
    ViewBag.Email = model.Email;
   }
   else
   {
    foreach (var item in result.Errors)
    {
     ModelState.AddModelError(item.PropertyName, item.ErrorMessage);
    }
   }
   return View(model);
  }
 }
}

 

修改一下,默认的路由:

public static void RegisterRoutes(RouteCollection routes)
  {
   routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

   routes.MapRoute(
    name: "Default",
    url: "{controller}/{action}/{id}",
    defaults: new { controller = "Customer", action = "Index", id = UrlParameter.Optional }
   );
  }

什么都不输入,直接点击Create:

输入Name,不输入Email

输入Name,Email输入非法的数据

输入合法的数据:

这里就完成了Fluent Validation验证。大家可以看到,这样的验证是不是干净简洁多了,配置信息都在一个类中,方便维护和扩展。不想数据注解那样,把验证信息和实体混合了。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

您可能感兴趣的文章:
  • asp.net 验证码生成和刷新及验证
  • Asp.net Mvc 身份验证、异常处理、权限验证(拦截器)实现代码
  • ASP.net 验证码实现代码(C#)
  • asp.net(C#) 生成随机验证码的代码
  • ASP.NET表单验证方法详解
  • jQuery 验证插件 Web前端设计模式(asp.net)
  • Asp.net(C#)实现验证码功能代码
  • 注册页实现激活邮箱验证(asp.net c#)
  • asp.net身份验证方式介绍
  • asp.net 简单验证码验证实现代码

今天关于asp.net-mvc – Fluent Validation,Domain和ViewModelsfluent uninitialized flow field的介绍到此结束,谢谢您的阅读,有关.net – MVC,ViewModels和Validation、ASP.Net MVC C#另一个viewmodel中的两个viewmodel – 如何在视图中引用、ASP.NET MVC – 用于编辑的ViewModels、ASP.NET MVC5验证系列之Fluent Validation等更多相关知识的信息可以在本站进行查询。

本文标签: