我通过一个 JavaScript 处理程序(我使用 jQuery)向我的 ASP.NET MVC 3 服务器提交一个表单,并在另一个 JavaScript 处理程序中接收来自服务器的错误响应。我想知道我应该如何在视图中显示由表单提交产生的错误消息?我更喜欢使用一些标准的 ASP.NET MVC 3 idiom/construct。
编辑
请注意,我想显示来自服务器的错误消息,这些消息是在 JavaScript 错误处理函数中接收到的。
我通过一个 JavaScript 处理程序(我使用 jQuery)向我的 ASP.NET MVC 3 服务器提交一个表单,并在另一个 JavaScript 处理程序中接收来自服务器的错误响应。我想知道我应该如何在视图中显示由表单提交产生的错误消息?我更喜欢使用一些标准的 ASP.NET MVC 3 idiom/construct。
编辑
请注意,我想显示来自服务器的错误消息,这些消息是在 JavaScript 错误处理函数中接收到的。
您可以采用纯 MVC 方式:http ://www.asp.net/mvc/tutorials/creating-a-mvc-3-application-with-razor-and-unobtrusive-javascript
向下滚动到“启用客户端验证”。
在您的视图中,您将拥有如下所示的代码:
@Html.TextBoxFor(model => model.UserName)
@Html.ValidationMessageFor(model => model.UserName)
更新
似乎 OP 对自定义消息传递感兴趣。这种自定义消息传递没有任何 MVC 构造。最好的办法是创建自己的消息区域并在回调函数中向其写入消息。不应该太复杂!
$.ajax(..., function(data) {
$('#errors').append('<p>' + data + '</p>');
});
假设您使用的是 MVC 解决方案模板附带的 jQuery validate,那么在您的 javascript 处理程序中,您必须向验证器添加错误。在验证器上有一个showErrors
方法。
在客户端:
var formSubmitCallback = function(result){
var validator = $(this).data('validator');
if(!result.IsValid && validator)
validator.showErrors(result.Errors); // uses jquery validator to highlight the fields
// process the rest of the result here
// if result.Action == ActionTypes.Redirect
// location.href = result.Url
// etc
}
现在我必须对来自服务器的结果对象进行标准化,以返回格式为 .json 的 json 对象{ "FieleName": "Error Message" }
。我在服务器端构建了一些Controller
和ViewModel
扩展来实现这一点。
在服务器端:
public ActionResult SomeAction(Model someModel){
if(ModelState.IsValid)
// save
else
// other stuff
// always return this.AjaxSubmit.
// Extension function will add Errors, and IsValid to the response data
return this.AjaxSubmit(new ClientAction{
Action = ClientActionType.Redirect,
Url = "/Some/Redirect/Route"
});
}
注意:现在回想起来,我确实编写了一些自定义代码来使其工作。我最终将添加客户端和服务器代码,以及 github 上的示例。但这是一般的想法。
您需要的服务器类和扩展如下
// GetAllErrors is a ModelState extension to format Model errors for Json response
public static Dictionary<string, string> GetAllErrors(this ModelStateDictionary modelState)
{
var query = (from state in modelState
where state.Value.Errors.Count > 0
group state by state.Key into g
select new
{
FieldName = g.Key,
FieldErrors = g.Select(prop => prop.Value.Errors).First().Select(prop => prop.ErrorMessage).ToList()
});
return query.ToDictionary(k => k.FieldName, v => string.Join("<br/>", v.FieldErrors));
}
// Controller result extension to return from actions
public static JsonResult AjaxSubmit(this Controller controller, ClientAction action)
{
if (controller == null) return new JsonResult { Data = action };
var result = new AjaxSubmitResult
{
Errors = controller.ModelState.GetAllErrors(),
IsValid = controller.ModelState.IsValid,
ClientAction = action
};
return new JsonResult{ Data = result };
}
// Action to perform on the client after a successful, valid response
public class ClientAction
{
public ClientActionType Action { get; set; }
public string Url { get; set; }
public string Function { get; set; }
public object Data { get; set; }
public Dictionary<string, string> Updatables { get; set; }
}
public enum ClientActionType
{
Redirect,
Ajax,
Function,
Modal,
Message,
FunctionAndMessage
}
服务器应以标准化消息进行响应。该消息可能包含完整的错误消息 (HTML),然后您可以将其显示在作为_Layout
页面一部分的空 div 中:
function(response) {
if(response.Status === "error") {
$("#errorContainer").html(response.ErrorHtml);
} else {
// the success handler
}
}
好处是您可以在服务器上执行相当标准化的错误消息呈现。当然,您也可以将这些显示为 js 弹出窗口/模态对话框等。
错误消息的格式是通过 CSS 完成的,可以非常普遍地应用于#errorContainer
其内容。
您可能会争辩说,使用来自服务器的纯文本进行响应并通过 JS 在客户端中添加任何 html 会更简洁。这也是可能的,并且可能更适用于“真正的”REST API。但是,它不允许使用格式化的错误消息(例如,带有链接等)
我过去在此问题上回答了类似的问题,以添加错误消息。
由于您希望错误从服务器返回,我假设是您已知的 javascript 方法,只需添加
var ul = $("#validationSummary ul"); ul.append("<li>Custom Error Message</li>")
我这样做的方式是:
创建基本控制器类并覆盖 OnException 处理程序
public abstract class MyBaseController : Controller
{
protected override void OnException(ExceptionContext filterContext)
{
if (filterContext.RequestContext.HttpContext.Request.IsAjaxRequest())
{
// add my own status code
Response.StatusCode = 550;
// write the error message to the response
Response.Write(filterContext.Exception.Message);
// mark the exception as handled
filterContext.ExceptionHandled = true;
}
base.OnException(filterContext);
}
}
在准备好文档的客户端上,我为 ajax 错误注册了全局处理程序
$(document).ready(function(){
$.ajaxSetup({
error:function(x,e){
if(x.status==0){
alert('You are offline!!\n Please Check Your Network.');
}else if(x.status==404){
alert('Requested URL not found.');
}else if(x.status==550){ // <----- THIS IS MY CUSTOM ERROR CODE --------
alert(x.responseText);
}else if(x.status==500){
alert('Internel Server Error.');
}else if(e=='parsererror'){
alert('Error.\nParsing JSON Request failed.');
}else if(e=='timeout'){
alert('Request Time out.');
}else {
alert('Unknow Error.\n'+x.responseText);
}
}
});
});
您当然可以调整此方法以满足您的需求。希望这可以帮助。