在MVC流利的验证:指定规则集客户端验证 [英] Fluent Validation in MVC: specify RuleSet for Client-Side validation

查看:194
本文介绍了在MVC流利的验证:指定规则集客户端验证的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的ASP.NET MVC 4项目我已经验证了我的看法的机型,包含规则规则集定义之一。中邮动作中使用修改规则集,当所有客户端验证通过。 网​​址电子邮件规则集修改规则集使用规则(你可以看到它下面),并在确认只有电子邮件和特殊阿贾克斯行动只会相应的URL。

我的问题是,视图不知道它应该使用客户端HTML设置<​​code>修改规则属性生成,并使用默认规则集,里面是空的。 我怎么能告诉视图用于输入设置修改规则属性代?

型号:

 公共类ShopInfoViewModel
{
    众长ShopId {搞定;组; }    公共字符串名称{;组; }    公共字符串网址{搞定;组; }    公共字符串描述{搞定;组; }    公共字符串电子邮件{获得;组; }
}

验证:

 公共类ShopInfoViewModelValidator:AbstractValidator&LT; ShopInfoViewModel&GT;
{
    公共ShopInfoViewModelValidator()
    {
        VAR shopManagementService = ServiceLocator.Instance.GetService&LT; IShopService&GT;();        规则集(编辑,()=&GT;
        {
            RuleFor(X =&GT; x.Name)
                .NotEmpty()。WithMessage(输入名称。)
                。长度(0,255).WithMessage(姓名长度不能超过255个字符。);            RuleFor(X =&GT; x.Description)
                .NotEmpty()。WithMessage(输入名称。)
                。长度(0,10000).WithMessage(姓名长度不能超过10000个字符。);            ApplyUrlRule(shopManagementService);
            ApplyEmailRule(shopManagementService);
        });        规则集(URL,()=&GT; ApplyUrlRule(shopManagementService));
        规则集(电子邮件,()=&GT; ApplyEmailRule(shopManagementService));
    }    私人无效ApplyUrlRule(IShopService shopService)
    {
        RuleFor(X =&GT; x.Url)
            .NotEmpty()。WithMessage(输入网址。)
            。长度(4,30).WithMessage(字符长度和30之间4)。
            .Matches(@[A-Z \\ - \\ D])WithMessage(不正确的格式。)。
            。必须((型号,URL)=&GT; shopService.Available(URL,model.ShopId))。WithMessage(店这个网址已经存在。);
    }    私人无效ApplyEmailRule(IShopService shopService)
    {
        //类似URL规则:不为空,长度,正则表达式,必须检查是否有独特
    }
}

验证操作实例:

 公众的ActionResult ValidateShopInfoUrl([CustomizeValidator(规则集=URL)]
        ShopInfoViewModel infoViewModel)
 {
     返回验证(ModelState中);
 }

获取和发布动作 ShopInfoViewModel

  [HTTPGET]
公众的ActionResult ShopInfo()
{
    VAR视图模型= OwnedShop.ToViewModel();
    返回PartialView(_ ShopInfo视图模型);
}[HttpPost]
公众的ActionResult ShopInfo(CustomizeValidator(规则集=编辑)] ShopInfoViewModel infoViewModel)
    {
        VAR成功= FALSE;        如果(ModelState.IsValid)
        {
            //保存逻辑放在这里
        }
    }

查看包含下一code:

  @ {
    Html.EnableClientValidation(真);
    Html.EnableUnobtrusiveJavaScript(真);
}
&LT;窗​​体类=主表行动=@ Url.RouteUrl(ManagementRoutes.ShopInfo)方法=POSTID =masterforminfo&GT;
    @ Html.TextBoxFor(X =&GT; x.Name)
    @ Html.TextBoxFor(X =&GT; x.Url,新{validationUrl = Url.RouteUrl(ManagementRoutes.ValidateShopInfoUrl)})
    @ Html.TextAreaFor(X =&GT; x.Description)
    @ Html.TextBoxFor(X =&GT; x.Email,新{validationUrl = Url.RouteUrl(ManagementRoutes.ValidateShopInfoEmail)})
    &LT;输入类型=提交名称=asdfasfdVALUE =Сохранить的风格=显示:无&GT;
&LT; /表及GT;

结果HTML输入(无需任何客户端验证属性):

 &LT;输入名称=名称TYPE =文本值=超级店/&GT;


解决方案

在FluentValidation来源挖后,我发现解决方案。告诉您要使用特定的规则集来看,装点你的动作,即返回视图, RuleSetForClientSideMessagesAttribute

  [HTTPGET]
[RuleSetForClientSideMessages(编辑)]
公众的ActionResult ShopInfo()
{
    VAR视图模型= OwnedShop.ToViewModel();
    返回PartialView(_ ShopInfo视图模型);
}

如果你需要指定多个规则集 - 使用另一个构造函数重载和独立的规则集​​用逗号:

  [RuleSetForClientSideMessages(编辑,电子邮件,URL)]
公众的ActionResult ShopInfo()
{
    VAR视图模型= OwnedShop.ToViewModel();
    返回PartialView(_ ShopInfo视图模型);
}

如果您需要决定哪些规则集将被直接用于操作 - 您可以通过将在HttpContext的下一个方式阵列( RuleSetForClientSideMessagesAttribute 当前未设计为破解FluentValidation被覆盖的):

 公众的ActionResult ShopInfo(validateOnlyEmail)
{
    VAR emailRuleSet =新[] {电子邮件};
    VAR allRuleSet =新[] {编辑,地址,电子邮件};    VAR actualRuleSet = validateOnlyEmail? emailRuleSet:allRuleSet;
    filterContext.HttpContext.Items [_ FV_ClientSideRuleSet] = actualRuleSet;    返回PartialView(_ ShopInfo视图模型);
}

不幸的是,大约有官方文档在此属性没有资料。

In my ASP.NET MVC 4 project I have validator for one of my view models, that contain rules definition for RuleSets. Edit ruleset used in Post action, when all client validation passed. Url and Email rule sets rules used in Edit ruleset (you can see it below) and in special ajax actions that validate only Email and only Url accordingly.

My problem is that view doesn't know that it should use Edit rule set for client html attributes generation, and use default rule set, which is empty. How can I tell view to use Edit rule set for input attributes generation?

Model:

public class ShopInfoViewModel
{
    public long ShopId { get; set; }

    public string Name { get; set; }

    public string Url { get; set; }

    public string Description { get; set; }

    public string Email { get; set; }
}

Validator:

public class ShopInfoViewModelValidator : AbstractValidator<ShopInfoViewModel>
{
    public ShopInfoViewModelValidator()
    {
        var shopManagementService = ServiceLocator.Instance.GetService<IShopService>();

        RuleSet("Edit", () =>
        {
            RuleFor(x => x.Name)
                .NotEmpty().WithMessage("Enter name.")
                .Length(0, 255).WithMessage("Name length should not exceed 255 chars.");

            RuleFor(x => x.Description)
                .NotEmpty().WithMessage("Enter name.")
                .Length(0, 10000).WithMessage("Name length should not exceed 10000 chars.");

            ApplyUrlRule(shopManagementService);
            ApplyEmailRule(shopManagementService);
        });

        RuleSet("Url", () => ApplyUrlRule(shopManagementService));
        RuleSet("Email", () => ApplyEmailRule(shopManagementService));
    }

    private void ApplyUrlRule(IShopService shopService)
    {
        RuleFor(x => x.Url)
            .NotEmpty().WithMessage("Enter url.")
            .Length(4, 30).WithMessage("Length between 4 and 30 chars.")
            .Matches(@"[a-z\-\d]").WithMessage("Incorrect format.")
            .Must((model, url) => shopService.Available(url, model.ShopId)).WithMessage("Shop with this url already exists.");
    }

    private void ApplyEmailRule(IShopService shopService)
    {
        // similar to url rule: not empty, length, regex and must check for unique
    }
}

Validation action example:

 public ActionResult ValidateShopInfoUrl([CustomizeValidator(RuleSet = "Url")]
        ShopInfoViewModel infoViewModel)
 {
     return Validation(ModelState);
 }

Get and Post actions for ShopInfoViewModel:

[HttpGet]
public ActionResult ShopInfo()
{
    var viewModel = OwnedShop.ToViewModel();
    return PartialView("_ShopInfo", viewModel);
}

[HttpPost]
public ActionResult ShopInfo(CustomizeValidator(RuleSet = "Edit")]ShopInfoViewModel infoViewModel)
    {
        var success = false;

        if (ModelState.IsValid)
        {
            // save logic goes here
        }
    }

View contains next code:

@{
    Html.EnableClientValidation(true);
    Html.EnableUnobtrusiveJavaScript(true);
}
<form class="master-form" action="@Url.RouteUrl(ManagementRoutes.ShopInfo)" method="POST" id="masterforminfo">
    @Html.TextBoxFor(x => x.Name)
    @Html.TextBoxFor(x => x.Url, new { validationUrl = Url.RouteUrl(ManagementRoutes.ValidateShopInfoUrl) })
    @Html.TextAreaFor(x => x.Description)
    @Html.TextBoxFor(x => x.Email, new { validationUrl = Url.RouteUrl(ManagementRoutes.ValidateShopInfoEmail) })
    <input type="submit" name="asdfasfd" value="Сохранить" style="display: none">
</form>

Result html input (without any client validation attributes):

<input name="Name" type="text" value="Super Shop"/> 

解决方案

After digging in FluentValidation sources I found solution. To tell view that you want to use specific ruleset, decorate your action, that returns view, with RuleSetForClientSideMessagesAttribute:

[HttpGet]
[RuleSetForClientSideMessages("Edit")]
public ActionResult ShopInfo()
{
    var viewModel = OwnedShop.ToViewModel();
    return PartialView("_ShopInfo", viewModel);
}

If you need to specify more than one ruleset — use another constructor overload and separate rulesets with commas:

[RuleSetForClientSideMessages("Edit", "Email", "Url")]
public ActionResult ShopInfo()
{
    var viewModel = OwnedShop.ToViewModel();
    return PartialView("_ShopInfo", viewModel);
}

If you need to decide about which ruleset would be used directly in action — you can hack FluentValidation by putting array in HttpContext next way (RuleSetForClientSideMessagesAttribute currently is not designed to be overriden):

public ActionResult ShopInfo(validateOnlyEmail)
{
    var emailRuleSet = new[]{"Email"};
    var allRuleSet = new[]{"Edit", "Url", "Email"};

    var actualRuleSet = validateOnlyEmail ? emailRuleSet : allRuleSet;
    filterContext.HttpContext.Items["_FV_ClientSideRuleSet"] = actualRuleSet;

    return PartialView("_ShopInfo", viewModel);
}

Unfortunately, there are no info about this attribute in official documentation.

这篇关于在MVC流利的验证:指定规则集客户端验证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆