【问题标题】:Validation message is not showing on client side验证消息未显示在客户端
【发布时间】:2016-04-22 12:28:04
【问题描述】:

这是我的模型

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>

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

【问题讨论】:

  • 改用@Html.ValidationMessageFor(model =&gt; model.Title)
  • 这个视图的目的是显示现有Asset的集合并有一个表单来创建一个新的Asset吗?在这种情况下,您的表单中的所有代码都不会正常工作,尤其是验证,因为您的模型没有名为 TitleDescription 等的属性,因此没有什么可以验证的。
  • @StephenMuecke 此视图将在表中显示记录,我有添加资产选项,其中一个模式弹出窗口将插入资产。 (imgur.com/GqImWXR) 和 (imgur.com/NgkLiD7)
  • 好的,现在我明白了你想要做什么(我假设你通过 ajax 提交表单,这样你就可以继续添加和编辑?)你需要一种不同的方法,因为你创建表单控制与您的模型没有关系,因此不会发生验证(始终,始终使用强类型 xxxFor() 辅助方法)。我需要休息一下,但我会在早上添加一个答案,说明如何解决此问题以及您的代码中的许多其他问题。
  • 但你可能想看看这个DotNetFiddle

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


【解决方案1】:

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

@model IEnumerable<Asset>

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

@Html.TextBox("Title")

创建&lt;input name="Title" id = "Title" value="" /&gt;,但IEnumerable&lt;Asset&gt; 没有名为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 属性并将其返回给视图。

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&lt;Asset&gt; 并创建一个局部视图,该视图返回您的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. 考虑在视图模型中添加一个属性,以便类名 避免视图中丑陋的switch 语句(设置在 控制器)
  6. 删除操作应该是 POST,而不是 GET

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

【讨论】:

  • 您提供的DotNetFiddle ..它将在我的数据库中为我创建2个表。但我只想要一张桌子用于该视图。所以我应该选择部分视图
  • 什么意思它将在我的数据库中为我创建 2 个表?它不会创建任何表。它只是将表单中的数据保存到一个表中,然后使用您保存的内容更新视图。或者你的意思是它为AssetVM 创建一个表?如果是这样,那么AssetVM 需要在一个单独的文件夹中(比如ViewModels),而不是在您的数据模型文件夹中。它是一个视图模型,与 EF 和您的数据模型无关。
  • 如果我为所有必须显示和添加类似此页面的记录的页面创建部分视图,这是一种好习惯吗?
  • 您可以根据需要使用部分(但该部分仍应基于视图模型,而不是数据模型)
  • 非常感谢斯蒂芬..您的建议很有效。我不能使用我现在使用的相同文件上传选项。单击删除图标后,删除选项也将转到控制器,但您说它应该是发布而不是获取(没有得到您)
猜你喜欢
  • 2012-08-24
  • 2016-10-11
  • 2012-09-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-09
  • 2016-03-29
  • 2012-11-09
相关资源
最近更新 更多