asp.net-mvc - 验证消息未显示在客户端

标签 asp.net-mvc validation client-side-validation

这是我的模型

public partial class Asset
{
    public long ID { get; set; }
    [RegularExpression("^[0-9]*$", ErrorMessage = "Title must be numeric")]
    public string Title { get; set; }
    public string Description { get; set; }
}

在我看来

<div class="Content-inner-pages">
<div class="TopHeading TopHeading2">
    <h2>Assets</h2>
    @* @Html.ActionLink("Create", "Create")*@
    <a class="CreateBtn AssetsBtn" href="Javascript:void(0);" onclick="javascript: HideUpdateButton();">Add Asset</a>
    <div class="clearfix"></div>
</div>
<input type="hidden" id="hdnIsNew" value="1" />
<input type="hidden" id="hdnRecId" />
<!-- Slide Popup panel -->
<div class="cd-panel from-right AddAssetForm">
    <header class="cd-panel-header">
        <h3>Add Asset</h3>
        <a href="javascript:void(0);" onclick="javascript: DisplayClear();" class="cd-panel-close">Close</a>
    </header>
    <div class="cd-panel-container">
        <div class="cd-panel-content">
            <!-- Add Reminder -->
            <div class="form-horizontal form-details popup-box">
                @using (Html.BeginForm("AssetsPage", "SuperAdmin", FormMethod.Post, new { enctype = "multipart/form-data" }))
                {
                    <div class="form-group">
                        <label class="col-md-5 control-label">
                            Asset Title
                        </label>
                        @Html.TextArea("ID", "", new { @class = "form-control", @id = "ID", @style = "display:none;" })
                        <div class="col-md-7">
                            @Html.TextBox("Title", "", new { @class = "form-control", @id = "Title", required = "required" })
                            @Html.ValidationMessage("Title", "*")

                        </div>
                    </div>
                    <div class="form-group">
                        <label class="col-md-5 control-label">Description</label>
                        <div class="col-md-7">
                            @Html.TextArea("Description", "", new { @class = "form-control", @id = "Description", required = "required" })
                            @Html.ValidationMessage("Description", "*")
                        </div>
                    </div>

                    <div class="form-group">
                        <label class="col-md-5 control-label">Attachment</label>
                        <div class="col-md-7">
                            <input type="file" name="file" id="filena" class="custom-file-input" required="required">
                            @Html.ValidationMessage("file", "*")

                        </div>
                    </div>
                    <div class="form-group">
                        <div class="col-md-7 col-md-offset-5">

                            <input type="submit" id="SaveBtn" value="Save" name="actiontype" class="btn-class btn-success">
                            <input type="submit" id="UpdateBtn" value="Update" name="actiontype" class="btn-class btn-success">

                        </div>
                    </div>
                }
            </div><!-- End Add Reminder -->

        </div> <!-- cd-panel-content -->
    </div> <!-- cd-panel-container -->
</div> <!-- cd-panel -->

<div class="box">
    <div class="box-content Custom-DataTable">
        <table id="AdministationAssets" class="table table-hover dt-responsive CustomDatable AdministationAssetsTable" cellspacing="0" width="100%">
            <thead>
                <tr>
                    <th style="width:5%;">Assets</th>
                    <th style="width:15%;">
                        @Html.DisplayNameFor(model => model.Title)
                    </th>
                    <th style="width:50%;">
                        @Html.DisplayNameFor(model => model.Description)
                    </th>
                    <th style="width:8%;">Options</th>
                </tr>
            </thead>
            <tbody>

                @foreach (var item in Model)
                {
                    <tr>
                        <td id="target" class="">
                            @{
                    switch (item.Extenstion.ToLower())
                    {
                        case "doc":
                            <i class="fa fa-file-word-o text-primary AssetIcon"></i>
                            break;
                        case "docx":
                        <i class="fa fa-file-word-o text-primary AssetIcon"></i>
                            break;
                        case "xls":
                        <i class="fa fa-file-excel-o text-success AssetIcon"></i>
                            break;
                        case "xlsx":
                        <i class="fa fa-file-excel-o text-success AssetIcon"></i>
                            break;
                        case "ppt":
                        <i class="fa fa-file-powerpoint-o text-danger AssetIcon"></i>
                            break;
                        case "jpg":
                        <i class="fa fa-file-photo-o text-warning AssetIcon"></i>
                            break;
                        case "png":
                        <i class="fa fa-file-photo-o text-warning AssetIcon"></i>
                            break;
                        case "pdf":
                        <i class="fa fa-file-pdf-o text-danger AssetIcon"></i>
                            break;
                        case "zip":
                        <i class="fa fa-file-archive-o text-muted AssetIcon"></i>
                            break;
                        case "htm":
                        <i class="fa fa-file-code-o text-info AssetIcon"></i>
                            break;
                        case "txt":
                        <i class="fa  fa-file-text-o text-info AssetIcon"></i>
                            break;
                        case "mov":
                        <i class="fa  fa-file-movie-o text-warning AssetIcon"></i>
                            break;
                        case "mp3":
                        <i class="fa fa-file-audio-o text-warning AssetIcon"></i>
                            break;

                        default:
                        <i class="fa fa-file AssetIcon"></i>
                            break;
                    }
                            }
                        </td>
                        <td>
                            @Html.DisplayFor(modelItem => item.Title)
                        </td>
                        <td>
                            @Html.DisplayFor(modelItem => item.Description)
                        </td>
                        <td>
                            @Html.ActionLink("Download", "DownloadAsset", new { id = item.ID }, new { @class = "ActionInvoice" })
                            @Html.ActionLink("Edit", "AddEditRecord", new { id = item.ID }, new { @class = "ActionEdit AssetEdit", onclick = "javascript:GetEditDetails(" + item.ID + ")" })
                            @Html.ActionLink("Delete", "AssetDelete", new { id = item.ID }, new { @class = "ActionDelete", onclick = "return confirm('Are You Sure delete this record?');", })

                        </td>
                    </tr>
                }
            </tbody>
        </table>
    </div>
</div>

问题是必填字段和正则表达式数字正在进行验证,但正则表达式没有显示错误消息,因为我想显示该错误:标题必须是数字。 请让我知道我在应用验证时哪里做错了。

最佳答案

您没有得到任何验证的原因是您 View 中的模型是

@model IEnumerable<Asset>

并且您为模型中不存在的属性生成输入

@Html.TextBox("Title")

创建<input name="Title" id = "Title" value="" />但是IEnumerable<Asset>没有名为 Title 的属性所以不data-val-*生成属性,因此没有规则添加到 $.validator生成客户端验证。

请注意,您获得的唯一验证是添加 new { required = "required" } 的结果。属性仅是 HTML-5 验证,不会为您提供必要的服务器端验证。

您可以通过创建 View 模型来解决这个问题

public class AssetVM
{
    public long? ID { get; set; }
    [Required(ErrorMessage = "Please enter a title")]
    [RegularExpression("^[0-9]*$", ErrorMessage = "Title must be numeric")]
    public string Title { get; set; }
    [Required(ErrorMessage = "Please enter a description")]
    public string Description { get; set; }
    public IEnumerable<Asset> Assets { get; set; }
}

并在 Controller 中初始化一个新的 AssetVM并填充Assets属性与集合并将其返回到 View 。

var model = new AssetVM()
{
    Assets = .... // your query
};
return View(model);

并在 View 中

@model AssestVM
....
@using (Html.BeginForm("AssetsPage", "SuperAdmin", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
    @Html.HiddenFor(m => m.ID)
    ....
    @Html.TextBoxFor(m => m.Title, new { @class = "form-control"})
    @Html.ValidationMessage(m => m.Title)
    ....
}
....
@foreach(var asset in Model.Assets)
{
    // build your table
}

另一种选择是保留现有的 @model IEnumerable<Asset>并创建一个部分 View ,返回 Asset 的表单然后在主视图中使用 @Html.Partial("_Asset", new Asset() )在主视图中生成表单。

旁注:

  1. 使用@Html.HiddenFor()生成 ID 的输入,不是一个 文本区域样式为隐藏
  2. 无需使用new { id = "###" } - HtmlHelper 方法已经添加 id属性和你刚刚覆盖 具有相同值的值
  3. 删除 new { required = "required" }属性使用 Unobtrusive Javascript而不是污染你的标记 行为
  4. 由于您还要上传文件,因此 View 模型也应该 包含属性public HttpPostedFileBase File { get; set; } 形式为@Html.TextBoxFor(m => m.File, new { type = "file" }) 。您还应该考虑文件显示名称的属性 这样就可以在 View 中输出了
  5. 考虑将类名的属性添加到 View 模型中 避免丑陋switch View 中的语句(设置在 Controller )
  6. 删除操作应该是 POST,而不是 GET

有关如何实现此功能的工作示例,请参阅 this DotNetFiddle ,尽管在您的情况下,因为您还上传文件,所以您需要使用 FormData 发布表单如 this answer 中所述

关于asp.net-mvc - 验证消息未显示在客户端,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36793845/

相关文章:

JavaScript REST 身份验证

validation - Asp.Net MVC EnableClientValidation 不起作用

asp.net - VimService55.XmlSerializers.dll 中发生类型 'System.StackOverflowException' 的未处理异常

css - asp 设计显示和呈现的浏览器显示不一样?

asp.net-mvc - 如何使用 EF 数据库优先实现继承

php - 使 zend EmailAddress 表单验证器仅返回一条自定义错误消息

c# - Elmah 没有记录 HttpRequestValidationException

forms - 通过验证更改用户密码( symfony2 )

asp.net-mvc - MVC : How to make DropdownList field (with Chosen Plugin) Required

asp.net-mvc-3 - 如何关闭 MVC 3 中的客户端验证?