Ajax.BeginForm 验证模型

Posted

技术标签:

【中文标题】Ajax.BeginForm 验证模型【英文标题】:Ajax.BeginFrom validate against model 【发布时间】:2014-01-07 05:37:29 【问题描述】:

我是 ASP.Net MVC 的新手..

问题来了……

我有一个列出所有过滤器类型的视图。在同一个视图中..我需要一个基于 AJAX 的搜索选项。我得到了ajax部分的工作。但是如何使 Ajax 帖子针对 UserEnity 模型进行验证?是否可以将视图的 Ajax 部分移动到 partialView ?

非常感谢任何帮助。

这里是示例

@model IEnumerable<UserEntity>

@using (Ajax.BeginForm("Index", "FiltrationType", new AjaxOptions
    
        HttpMethod = "post",
        UpdateTargetId = "gridContent",
        InsertionMode = InsertionMode.Replace ))
    
        @html.AntiForgeryToken();
        @Html.ValidationSummary(true)
        <p> <b>Search Filter Type </b> @Html.TextBox("SearchString") <br />   
        <input type="submit" name="cmdFiltrationSearch" value="Search" /> 
        <input type="submit" name="cmdFiltrationClear" value="Clear" onclick="ClearFiltrationTypeSearchText()" /> 
        </p>     
    

<div id="gridContent">

   @if (ViewBag.DataRetriveStatus != null )
   
     <span class ="ErrorDiv"> @ViewBag.DataRetriveStatus </span><br />
   
   else
   
   @Html.Partial("_filtrationGrid", Model)
   
</div>

好消息是,在链接表单名称以匹配模型实体名称之后,我无法发布模型数据。

@using (Ajax.BeginForm("Index", "User", new AjaxOptions

    HttpMethod = "post",
    UpdateTargetId = "gridContent",
    InsertionMode = InsertionMode.Replace ))    
    @Html.AntiForgeryToken();
    @Html.ValidationSummary(true)
    <table class ="UserSearch">
        <tr> 
            <th> Account </th>
            <td>@Html.TextBox("DisplayName")
             </td>
        </tr>
          <tr> 
            <th> First Name</th>
            <td>@Html.TextBox("FirstName")  </td>
        </tr>
          <tr> 
            <th> Last Name </th>
            <td>@Html.TextBox("LastName")  </td>
        </tr>
    </table>
    <p>   
    <input type="submit" name="cmdUserSearch" value="Search" /> 
    <input type="submit" name="cmdUserClear" value="Clear" onclick="ClearUserSearchText()" /> 
    </p>     

但是 jquery 验证在表单上不起作用..知道为什么吗?但是在控制器中验证为ModelState.IsValid 工作正常。

这是我的实体模型

public class UserSearch

    [Required(ErrorMessage = "Display Name is Required")]
    [StringLength(30, MinimumLength = 2, ErrorMessage = "Display Name length should be between 2 and 30 characters")]
    [Display(Name = "Display Name")]
    public string DisplayName  get; set; 

    [Required(ErrorMessage = "First Name is Required")]
    [StringLength(30, MinimumLength = 2, ErrorMessage = "First Name length should be between 2 and 30 characters")]
    [Display(Name = "First Name")]
    public string FirstName  get; set; 

    [Required(ErrorMessage = "Last Name is Required")]
    [StringLength(30, MinimumLength = 2, ErrorMessage = "Last Name length should be between 2 and 30 characters")]
    [Display(Name = "Last Name")]
    public string LastName  get; set; 

和控制器代码...

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Index(string cmdUserSearch, string cmdUserClear,  UserSearch entity)


   if (ModelState.IsValid) 
   
     // some code
   

【问题讨论】:

也许您可以发布您的控制器代码?您在这里提交的唯一内容似乎是一个字符串变量SearchString,您要绑定哪种模型? 感谢您的回复。我想绑定 UserEntity 模型。这是我的示例控制器 [HttpPost] [ValidateAntiForgeryToken] public ActionResult Index(string cmdFiltrationSearch, string cmdFiltrationClear, string SearchString, UserEntity entity) 当我调试时..实体值为空。 您也可以发布您的实体模型吗? 我刚刚更新了我的帖子,提供了更多信息。感谢您的入住,期待您的帮助。 我已经更新了答案。请检查 - 我已经在一个示例项目中尝试过这个 - 使用我认为您正在使用的 MVC 4 运行良好。 【参考方案1】:

此时我只能猜测,但最常见的解决方案是检查是否包含 jquery.validate.unobtrusive-ajax 脚本。

更新

以下另一个可能的原因:

很可能出现问题是因为您的模型是IEnumerable&lt;UserEntity&gt;。因此,HtmlHelper&lt;IEnumerable&lt;UserEntity&gt;&gt;(这是您用于呈现帮助程序的 Html 属性的类型)没有关于 UserEntity 验证规则的信息,并呈现类型等于 text 的简单输入,不需要属性客户验证。

这解释了为什么服务器端验证有效 - 您期望将 UserSearch 实例作为操作方法的参数,因此现在应用验证规则。

其中一种可能的解决方案是使用您希望使用内置验证在客户端上验证的属性来扩展模型。例如,您可以使用以下模型。

public class UserSearchResults : UserSearch

    public IEnumerable<UserEntity> Items  get; set; 

@model 必须更改为我们的新 UserSearchResults 类。 您必须更新您的控制器以将UserSearchResults 传递到视图中。 并将以下更改添加到剃须刀。

 <table class ="UserSearch">
    <tr> 
        <th> Account </th>
        <td>@Html.TextBoxFor(x => x.DisplayName)</td>
    </tr>
    <tr> 
        <th> First Name </th>
        <td>@Html.TextBoxFor(x => x.FirstName)</td>
    </tr>
    <tr> 
        <th> Last Name </th>
        <td>@Html.TextBoxFor(x => x.LastName)</td>
    </tr>
</table>

并更新局部视图的使用。

@Html.Partial("_filtrationGrid", Model.Items)

使用上面的代码将告诉HtmlHelper 它正在处理哪个模型以及应该应用验证。

在您的情况下,可能有更好的组合模型的方法,但主要的一点是,当视图被渲染时,引擎不知道这些输入的值将被发布到期望得到的操作方法UserSearch 类实例,因此它们被视为没有附加验证的普通输入。


这与问题无关,但我想知道为什么您的操作方法string cmdUserSearch, string cmdUserClear中有这些参数。根据您问题中的代码,这些代码始终等于null

同样最好将名称为cmdFiltrationClear的输入类型改为button而不是submit,否则有可能仍然会提交表单。

【讨论】:

cmdUserSearch, cmdUserClear 用于在控制器检查用户点击了哪个按钮。如果单击搜索..然后从数据库中提取数据并填充。如果单击 cler,然后使用 Jquery,我会将所有文本框设为空,并在控制器中填充表中的所有数据。 也与制作 UserSearchResults 一样。 My UserSearh 是在 UserEntity 中找到的属性子集。我用用户搜索表单中需要的属性创建了 UserSearch 类。在 UserSearch 类中,电子邮件没有用 [Required] 属性修饰,而在 UserEntity 中,电子邮件用 [Required] 属性修饰。在表单中,如果我将电子邮件设置为 @Html.EditorFor(model => model.Email) @Html.ValidationMessageFor(model => model.Email) 然后单击提交..form 显示“需要电子邮件”。【参考方案2】:

您的 web.config 文件是否已将这些值设置为 true?

<add key="ClientValidationEnabled" value="true" />
<add key="UnobtrusivejavascriptEnabled" value="true" />

至于将 ajax 部分包含为局部视图,您当然可以这样做。

【讨论】:

是的,我在 web.config 中有这个。 Jquery 验证在其他视图中工作正常。

以上是关于Ajax.BeginForm 验证模型的主要内容,如果未能解决你的问题,请参考以下文章

即使我通过另一个模型,Ajax.BeginForm 响应也包含以前的值

ASP.NET MVC 3 Ajax.BeginForm 意外重置模型值

使用目标 AJAX 和 ASP 将复杂模型传递给控制器

jQuery.Ajax与Ajax.beginform一起使用不引人注目的JavaScript

将 Ajax.BeginForm 与 A​​SP.NET MVC 3 Razor 一起使用

Ajax.BeginForm 处理两个不同的 onSuccess 响应,MVC 5,C#