客户端未显示验证消息

Validation message is not showing on client side

这是我的模型

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>

事情是必填字段和正则表达式数字编号正在发生验证,但正则表达式没有显示错误消息,因为我想显示该错误:标题必须是数字。 请让我知道我在申请验证时哪里做错了。

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

@model IEnumerable<Asset>

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

@Html.TextBox("Title")

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

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

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

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

并在控制器中,初始化一个新的 AssetVM 并使用集合填充 Assets 属性 并将其 return 填充到视图。

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

并在视图中

@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> 并创建一个局部视图 return 将您的表单用于 Asset 并在主视图中使用 @Html.Partial("_Asset", new Asset() ) 在主视图中生成表单。

旁注:

  1. 使用 @Html.HiddenFor() 生成 ID 的输入,而不是 文本区域样式为隐藏
  2. 没有必要使用new { id = "###" } - HtmlHelper 方法已经添加了 id 属性,您只需覆盖 具有相同值的值
  3. 删除 new { required = "required" } 属性 使用 Unobtrusive Javascript 而不是用 行为
  4. 既然你也在上传文件,视图模型也应该 包含一个 属性 public HttpPostedFileBase File { get; set; } 并以 @Html.TextBoxFor(m => m.File, new { type = "file" }) 的形式。您还应该考虑 属性 作为文件的显示名称 这样可以在视图中输出
  5. 考虑将 属性 添加到 class 名称的视图模型中 避免视图中难看的 switch 语句(设置在 控制器)
  6. 删除操作应该是 POST,而不是 GET

有关如何实施的工作示例,请参阅 this DotNetFiddle, although in your case, because you are also uploading a file, you would need to post the form using FormData as described in