Asp.net mvc ASP.NET MVC:如何使用Html.ValidationSummary向最终用户解释无效类型冲突?
这里有严重的n00b警告;请宽恕我 因此,我完成了这项工作,现在正在将一个VB.NET应用程序转换为ASP.NETMVC,使用Nerd晚餐程序作为一种粗略的模板 我使用“IsValid/GetRuleViolations()”模式来识别无效的用户输入或违反业务规则的值。我使用LINQ to SQL,并利用“OnValidate()”钩子,该钩子允许我运行验证,并在尝试通过CustomerRepository类保存对数据库的更改时引发应用程序异常 无论如何,一切都很好,只是当表单值到达我的验证方法时,无效类型已经转换为默认值或现有值。(我有一个整数的“StreetNumber”属性,尽管我认为这对于DateTime或任何其他非字符串也是一个问题。) 现在,我猜UpdateModel()方法会抛出一个异常,然后更改值,因为Html.ValidationMessage显示在StreetNumber字段旁边,但我的验证方法从未看到原始输入。这有两个问题:Asp.net mvc ASP.NET MVC:如何使用Html.ValidationSummary向最终用户解释无效类型冲突?,asp.net-mvc,validationsummary,Asp.net Mvc,Validationsummary,这里有严重的n00b警告;请宽恕我 因此,我完成了这项工作,现在正在将一个VB.NET应用程序转换为ASP.NETMVC,使用Nerd晚餐程序作为一种粗略的模板 我使用“IsValid/GetRuleViolations()”模式来识别无效的用户输入或违反业务规则的值。我使用LINQ to SQL,并利用“OnValidate()”钩子,该钩子允许我运行验证,并在尝试通过CustomerRepository类保存对数据库的更改时引发应用程序异常 无论如何,一切都很好,只是当表单值到达我的验证方法
客户控制器代码
// POST: /Customers/Edit/[id]
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Edit(int id, FormCollection formValues)
{
Customer customer = customerRepository.GetCustomer(id);
try
{
UpdateModel(customer);
customerRepository.Save();
return RedirectToAction("Details", new { id = customer.AccountID });
}
catch
{
foreach (var issue in customer.GetRuleViolations())
ModelState.AddModelError(issue.PropertyName, issue.ErrorMessage);
}
return View(customer);
}
这将是一个很好的起点: 但我认为将数据绑定到域对象是一种不好的做法 我个人的方法是使用带有todo验证的表示模型(这使得以后连接客户端验证变得很容易)。您还可以创建自己的ValidationAttributes,以连接到数据绑定验证中 如果它在数据绑定到POCO对象后有效,则向它传递一个执行更复杂的业务验证的服务。验证通过后,将其传递给另一个服务(或同一个服务),该服务将值传输到域对象,然后保存它 我不熟悉Linq到SQL GetRuleViolations模式,所以可以在适合的地方用该模式替换我的一个步骤 我会尽力在这里解释的 POCO演示模式:
public class EditCustomerForm
{
[DisplayName("First name")]
[Required(ErrorMessage = "First name is required")]
[StringLength(60, ErrorMessage = "First name cannot exceed 60 characters.")]
public string FirstName { get; set; }
[DisplayName("Last name")]
[Required(ErrorMessage = "Last name is required")]
[StringLength(60, ErrorMessage = "Last name cannot exceed 60 characters.")]
public string LastName { get; set; }
[Required(ErrorMessage = "Email is required")]
[RegularExpression(@"^([a-zA-Z0-9_\-\.]+)@((\[[0-9]{1,3}" +
@"\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\" +
@".)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$",
ErrorMessage = "Email appears to be invalid.")]
public string Email { get; set; }
}
控制器逻辑
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Edit(int id, EditCustomerForm editCustomerForm)
{
var editCustomerForm = CustomerService.GetEditCustomerForm(id);
return View(editCustomerForm);
}
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Edit(int id, EditCustomerForm editCustomerForm)
{
try
{
if (Page.IsValid)
{
//Complex business validation that validation attributes can't handle
//If there is an error, I get this method to throw an exception that has
//the errors in it in the form of a IDictionary<string, string>
CustomerService.ValidateEditCustomerForm(editCustomerForm, id);
//If the above method hasn't thrown an exception, we can save it
//In this method you should map the editCustomerForm back to your Cusomter domain model
CustomerService.SaveCustomer(editCustomerForm, id)
//Now we can redirect
return RedirectToAction("Details", new { id = customer.AccountID });
}
//ServiceLayerException is a custom exception thrown by
//CustomerService.ValidateEditCusotmerForm or possibly .SaveCustomer
catch (ServiceLayerException ex)
{
foreach (var kvp in ex.Errors)
ModelState.AddModelError(kvp.Key, kvp.Value);
}
catch (Exception ex) //General catch
{
ModelState.AddModelError("*", "There was an error trying to save the customer, please try again.");
}
return View(editCustomerForm);
}
[AcceptVerbs(HttpVerbs.Post)]
公共操作结果编辑(int-id,editCustomerPerform editCustomerPerform)
{
var editCustomerPerform=CustomerService.geteditCustomerPerform(id);
返回视图(EditCustomPerform);
}
[接受动词(HttpVerbs.Post)]
公共操作结果编辑(int-id,editCustomerPerform editCustomerPerform)
{
尝试
{
如果(第页有效)
{
//验证属性无法处理的复杂业务验证
//如果有错误,我会让这个方法抛出一个异常
//以字典形式出现的错误
CustomerService.ValidateEditCustomerPerform(编辑CustomerPerform,id);
//如果上面的方法没有抛出异常,我们可以保存它
//在这种方法中,您应该将editCustomerPerform映射回您的Cusomter域模型
CustomerService.SaveCustomer(编辑CustomerPerform,id)
//现在我们可以重定向了
返回重定向到操作(“详细信息”,新的{id=customer.AccountID});
}
//ServiceLayerException是由
//CustomerService.ValidateEditCustomerForm或可能的话.SaveCustomer
捕获(ServiceLayerException ex)
{
foreach(变量kvp在ex.Errors中)
AddModelError(kvp.Key,kvp.Value);
}
catch(Exception ex)//一般catch
{
AddModelError(“*”,“试图保存客户时出错,请重试。”);
}
返回视图(EditCustomPerform);
}
清晰如泥?如果您需要更多的澄清,请告诉我:-)
再说一遍,这只是我的方法。你可以先看我链接的Scott Gu的文章,然后从那里开始
HTHs,Charles哇,感谢您的详细回复!这将需要我一段时间来解析,但我一定会在沉浸其中后再查看。谢谢!您的帖子帮了我很大的忙!感谢您为我指明了正确的方向!