4

我通过一个 JavaScript 处理程序(我使用 jQuery)向我的 ASP.NET MVC 3 服务器提交一个表单,并在另一个 JavaScript 处理程序中接收来自服务器的错误响应。我想知道我应该如何在视图中显示由表单提交产生的​​错误消息?我更喜欢使用一些标准的 ASP.NET MVC 3 idiom/construct。

编辑

请注意,我想显示来自服务器的错误消息,这些消息是在 JavaScript 错误处理函数中接收到的。

4

5 回答 5

2

您可以采用纯 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>');
});
于 2011-09-02T14:27:39.843 回答
2

假设您使用的是 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" }。我在服务器端构建了一些ControllerViewModel扩展来实现这一点。

在服务器端

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
}
于 2011-09-02T14:27:53.900 回答
1

服务器应以标准化消息进行响应。该消息可能包含完整的错误消息 (HTML),然后您可以将其显示在作为_Layout页面一部分的空 div 中:

function(response) {
  if(response.Status === "error") {
    $("#errorContainer").html(response.ErrorHtml);
  } else {
    // the success handler
  }
}

好处是您可以在服务器上执行相当标准化的错误消息呈现。当然,您也可以将这些显示为 js 弹出窗口/模态对话框等。

错误消息的格式是通过 CSS 完成的,可以非常普遍地应用于#errorContainer其内容。

您可能会争辩说,使用来自服务器的纯文本进行响应并通过 JS 在客户端中添加任何 html 会更简洁。这也是可能的,并且可能更适用于“真正的”REST API。但是,它不允许使用格式化的错误消息(例如,带有链接等)

于 2011-09-02T14:37:50.673 回答
1

我过去在此问题上回答了类似的问题,以添加错误消息。

使用 JS 和动态 DOM 元素进行 MVC 验证摘要操作

由于您希望错误从服务器返回,我假设是您已知的 javascript 方法,只需添加


var ul = $("#validationSummary ul"); ul.append("<li>Custom Error Message</li>")

于 2011-09-02T16:31:58.190 回答
0

我这样做的方式是:

创建基本控制器类并覆盖 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);
        }
    }
});
});

您当然可以调整此方法以满足您的需求。希望这可以帮助。

于 2011-09-03T17:43:32.337 回答