MVC 4使用局部视图进行validation

我正在使用MVC 4和Entity Framework来开发一个Web应用程序。 我正在使用加载了javascript的部分视图。 其中之一是包含validation的创建视图。 这就是我的问题:validation。 我有一个自定义validation逻辑,例如,如果用户在某个字段(如“名称”)中输入了某些数字,则会显示错误。

在这里,使用部分视图,它将我的部分视图重定向到显示的错误,但我想要做的是留在我的主视图(索引视图)并保留显示错误的部分视图。

编辑:

这是我的部分观点:

@model BuSIMaterial.Models.Person @using (Html.BeginForm()) { @Html.ValidationSummary(true) 
Person
First name :
@Html.TextBoxFor(model => model.FirstName, new { maxlength = 50 }) @Html.ValidationMessageFor(model => model.FirstName)
Last name :
@Html.TextBoxFor(model => model.LastName, new { maxlength = 50 }) @Html.ValidationMessageFor(model => model.LastName)
National number :
@Html.TextBoxFor(model => model.NumNat, new { maxlength = 11 }) @Html.ValidationMessageFor(model => model.NumNat)
Start date :
@Html.TextBoxFor(model => model.StartDate, new {@class = "datepicker", @placeholder="yyyy/mm/dd"}) @Html.ValidationMessageFor(model => model.StartDate)
End date :
@Html.TextBoxFor(model => model.EndDate, new { @class = "datepicker", @placeholder = "yyyy/mm/dd" }) @Html.ValidationMessageFor(model => model.EndDate)
Distance House - Work (km) :
@Html.EditorFor(model => model.HouseToWorkKilometers) @Html.ValidationMessageFor(model => model.HouseToWorkKilometers)
Category :
@Html.DropDownList("Id_ProductPackageCategory", "Choose one ...") @Html.ValidationMessageFor(model => model.Id_ProductPackageCategory) Add a new category?
Upgrade? :
@Html.EditorFor(model => model.Upgrade) @Html.ValidationMessageFor(model => model.Upgrade)

} @section Scripts { @Scripts.Render("~/bundles/jqueryval") @Scripts.Render("~/bundles/jqueryui") @Styles.Render("~/Content/themes/base/css") }

在我看来,索引,我有这个:

 

以及我加载Partial View的方式:

  $("#create").click(function () { var form = $("#create_person").closest("form"); form.removeData('validator'); form.removeData('unobtrusiveValidation'); $.validator.unobtrusive.parse(form); $.ajax({ url: "/Person/CreateOrUpdate", type: "POST", data: $("#create_person").serialize(), cache: false }); // var url = '/Person/CreatePerson'; // $("#create_person").load(url); }); 

行动 :

 [HttpGet] public ActionResult CreateOrUpdate() { ViewBag.Id_ProductPackageCategory = new SelectList(db.ProductPackageCategories, "Id_ProductPackageCategory", "Name"); return View(); } [HttpPost] public JsonResult CreateOrUpdate(Person person) { ViewBag.Id_ProductPackageCategory = new SelectList(db.ProductPackageCategories, "Id_ProductPackageCategory", "Name", person.Id_ProductPackageCategory); try { if (!ModelState.IsValid) { string messages = string.Join("; ", ModelState.Values .SelectMany(x => x.Errors) .Select(x => x.ErrorMessage)); throw new Exception("Please correct the following errors: " + Environment.NewLine + messages); } db.Persons.AddObject(person); db.SaveChanges(); return Json(new { Result = "OK" }); } catch (Exception ex) { return Json(new { Result = "ERROR", Message = ex.Message }); } } 

如果您发布页面,它将不会返回到动态加载的局部视图。 尝试对/ Person / CreatePerson进行ajax调用。 您的CreatePerson看起来类似于

 [HttpPost] public JsonResult CreatePerson(Person person) { ViewBag.Id_ProductPackageCategory = new SelectList(db.ProductPackageCategories, "Id_ProductPackageCategory", "Name", person.Id_ProductPackageCategory); try { if (!ModelState.IsValid) { string messages = string.Join("; ", ModelState.Values .SelectMany(x => x.Errors) .Select(x => x.ErrorMessage)); throw new Exception("Please correct the following errors: " + Environment.NewLine + messages); } db.Persons.AddObject(person); db.SaveChanges(); return Json(new { Result = "OK" }); } catch (Exception ex) { return Json(new { Result = "ERROR", Message = ex.Message }); } } ` 

对/ Person / CreatePerson的ajax调用看起来类似于

`

 $.ajax({ url: '/Person/CreatePerson', type: "POST", data: $("#form").serialize(), success: function (responce) { alert(responce.Message); }, error: function (xhr, textStatus) { alert(xhr.status + " " + xhr.statusText); } }); 

除了不显眼的validation,动态内容也无法轻松完成。 在动态添加的局部视图上检查链接不显眼的validation(不工作)

我遇到了这种情况,我的主View使用Ajaxpost来检索PartialViews并将PartialView的标记传递到我的View中。 我使用jQueryvalidation框架来实现客户端不显眼的validation。 当我尝试validation通过Ajax调用加载到页面中的表单时,validation似乎没有起作用,我的表单只是发布了。 事实certificate,不显眼的jQueryvalidation器库在完成页面上所有validation规则的加载后解析页面的标记。 结果是,jQuery不知道动态添加的标记有任何validation规则,导致在post上没有抛出validation错误。

Traffy有一个可以在不显眼的jQuery库中公开访问的方法,你可以调用它,这会强制解析器扫描你刚刚加载的标记。 为此,您需要将以下代码添加到PartialView(或其他动态加载的内容)

 //this code goes in your partial view $(function(){ //allow the validation framework to re-prase the DOM jQuery.validator.unobtrusive.parse(); //or to give the parser some context, supply it with a selector //jQuery validator will parse all child elements (deep) starting //from the selector element supplied jQuery.validator.unobtrusive.parse("#formId"); }); 

然后在您的父页面中,您可以处理表单提交并检查表单是否有效;

 //then in your parent page handle the form submission $(function(){ $("#SubmitButton").click(function(){ if (!$("#Form1").valid()){ return false; } }); }); 

就是这样!! (信用:戴夫的编码)

我为此开发了一个不错的解决方法。 部分页面不会在回发时显示服务器错误。 首先,我们得到错误,将它们发送回页面,然后在javascript中创建它们并重新validation页面。 希望,嘿presto!

在你的控制器中:

  if (ModelState.IsValid) { //... whatever code you need in here } var list = ModelStateHelper.AllErrors(ModelState); TempData["shepherdErrors"] = list; 

我将它放在TempData中,因此可以从部分中轻松检索。 是的,我称之为shepherdErrors,这是我的想法所以我可以把这个概念称为我想要的愚蠢名字! 将错误代码应用到它们应该存在的位置或者是一般的想法。

在辅助类中:

 public class ModelStateHelper { public static IEnumerable> AllErrors(ModelStateDictionary modelState) { var result = new List>(); var erroneousFields = modelState.Where(ms => ms.Value.Errors.Any()) .Select(x => new { x.Key, x.Value.Errors }); foreach (var erroneousField in erroneousFields) { var fieldKey = erroneousField.Key; var fieldErrors = erroneousField.Errors .Select(error => new KeyValuePair(fieldKey, error.ErrorMessage)); //Error(fieldKey, error.ErrorMessage)); result.AddRange(fieldErrors); } return result; } } 

然后在jquery加载后的某个地方的html页面上:

 function displayShepherdErrors() { var shepherdErrors = JSON.parse('@(Newtonsoft.Json.JsonConvert.SerializeObject(TempData["shepherdErrors"]))'.replace(/"/g, '"')); var frm; var isShepherdErrors = (shepherdErrors && shepherdErrors.length > 0); if (isShepherdErrors) { errObj = {}; for (var i = 0; i < shepherdErrors.length; i++) { var errorKey = shepherdErrors[i].Key; //also the id of the field var errorMsg = shepherdErrors[i].Value; var reg = new RegExp('^' + errorKey + '$', 'gi'); //find the selector - we use filter so we can find it case insensitive var control = $('input').filter(function () { if ($(this).attr('id')) return $(this).attr('id').match(reg); }); if (control && control.length) { control = control[0]; var controlId = $(control).attr('name'); errObj[controlId] = errorMsg; //get the containing form of the first input element if (!frm) frm = control.form; } } var validator = $(frm).validate(); validator.showErrors(errObj); } return isShepherdErrors; } var isShepherdErrors = displayShepherdErrors(); 

这应该是开箱即用的一般MVC开发提供的,生成的文本框是基于变量名称 - 这是MVC的默认行为。