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