在ASP.NET MVC 3视图中,从JavaScript(jQuery)显示错误的推荐方法是什么?

时间:2011-09-02 14:20:03

标签: jquery asp.net-mvc-3 validation client-side-validation

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

修改

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

5 个答案:

答案 0 :(得分: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>');
});

答案 1 :(得分:2)

假设您正在使用MVC解决方案模板附带的jQuery验证,那么在您的javascript处理程序中,您将不得不向验证程序添加错误。有showErrors method on validator

在客户端

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
}

现在我必须从服务器标准化结果对象以返回用{ "FieleName": "Error Message" }格式化的json对象。我在服务器端构建了一些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
}

答案 2 :(得分: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。但是,它不允许使用格式化的错误消息(例如,使用链接等)

答案 3 :(得分:1)

我在过去就此添加了类似的内容,用于添加错误消息。

MVC Validation Summary manipulation with JS and Dynamic DOM elements

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


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

答案 4 :(得分: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);
        }
    }
});
});

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