Ajax异常和webapi异常处理

时间:2014-05-02 16:32:10

标签: c# jquery ajax asp.net-mvc asp.net-web-api

我想弄清楚如何将两个错误放在一起。

我的ajax异常处理工作正常。如果有一个ajax异常,我的[AJAXErrorHandlerAttribute]会捕获错误,并向用户显示错误消息。

我就是这样做的。下面的示例将数据发布到应用程序和数据库。然后数据库将适当的对象返回到视图并显示结果

$.ajax({
            url: '@Url.Action("LandingPageSearchResult", "Landing")',
            type: 'POST',
            dataType: 'json',
            cache: false,
            data: AddAntiForgeryToken({......}),
            success: function (result) {
                 DoSomething()
            },
            error: function (xhr, textStatus, errorThrown) {
                if (xhr.status == 500) {
                    var data = JSON.parse(xhr.responseText);
                    if (data && data.ErrorMessage) {
                        var url = '@Url.Action("ErrorPage", "Error", new { statusCode = "__statusCode__", ErrorMessage = "__ErrorMessage__", exceptionID = "__exceptionID__" })';
                        url = url.replace('__statusCode__', 500).replace('__ErrorMessage__', data.ErrorMessage.split(',')[1]).replace('__exceptionID__', data.ErrorMessage.split(',')[0]);
                        window.location.href = url;
                    }
                }
                else
                    alert("There was a problem with the operation. Please try again " + "Status: " + textStatus + "Error: " + errorThrown);
        });


public class AJAXErrorHandlerAttribute : HandleErrorAttribute
{
    public override void OnException(ExceptionContext filterContext)
    {
        if (filterContext.HttpContext.Request.IsAjaxRequest() && filterContext.Exception != null)
        {
            filterContext.HttpContext.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
            filterContext.Result = new JsonResult
            {
                JsonRequestBehavior = JsonRequestBehavior.AllowGet,
                Data = new
                {
                    filterContext.Exception.Message,
                    filterContext.Exception.StackTrace
                }
            };
            filterContext.ExceptionHandled = true;
        }
        else
        {
            base.OnException(filterContext);
        }
    }
}

现在我有一个将我的Web应用程序连接到数据库的web api。因此,我试图向用户显示错误是源自Api还是其他Ajax错误。有了我目前的我的api错误冒泡到ajax并始终显示500错误。这是因为我的属性中的这一行

filterContext.HttpContext.Response.StatusCode = (int)HttpStatusCode.InternalServerError;

让我用示例

更清楚

我正在以下列方式使用我的网络API

public List<AssociatedFile> GetListofFilesByCEQRAndMilestone(string CEQRNumber, string LatestMileStone)
    {
        List<AssociatedFile> fileList = new List<AssociatedFile>();

        using (var client = new HttpClient())
        {
            ........

            if (response.IsSuccessStatusCode)
            {
                var fileList = response.Content.ReadAsAsync<IEnumerable<AssociatedFileData>>().Result.ToList();

            }
            else
            {                  
                string responseBody = response.Content.ReadAsStringAsync().Result;
                throw new HttpException((int)response.StatusCode, responseBody);                    
            }

            return fileList; 
        }     
    }

现在我的ajax调用指的是

public ActionResult LandingPageSearchResult(ProjectList project)
    {
        List<Project> projectList = new List<Project>();
        PagedProjectList pagedList = new PagedProjectList();

        projectList.AddRange(list.Select(item =>
            new Project
            {
                .......

                AssociatedFileList = item.MilestoneData == null ? new List<AssociatedFile>() : GetListofFilesByCEQRAndMilestone(item.CEQRNumber, item.MilestoneData.LatestMileStone)
            }));

        .......

        var stringView = PartialJsonHelper.PartialView(this, "LandingPageSearchResult", pagedList);
        var jsonResult = Json(stringView, JsonRequestBehavior.AllowGet);
        jsonResult.MaxJsonLength = int.MaxValue;
        return jsonResult;
    }

我想要的是我的错误是由api抛出的

string responseBody = response.Content.ReadAsStringAsync().Result;
throw new HttpException((int)response.StatusCode, responseBody);  

或者我的ajax被Global.ascx.cs中的Application_Error中的全局异常处理捕获,并且默认情况下在web api中生成的错误代码不是500。

Global.ascx.cs中的我的Application_Error

protected void Application_Error(object sender, EventArgs e)
    {
        Exception exception = Server.GetLastError();
        Response.Clear();

        HttpException httpException = exception as HttpException;

        RouteData routeData = new RouteData();
        routeData.Values.Add("controller", "Error");

        if (httpException == null)
        {
            // clear error on server
            Server.ClearError();

            routeData.Values.Add("action", "ErrorPage");
        }
        else
        {
            switch (httpException.GetHttpCode())
            {
                case 404:
                    routeData.Values.Add("action", "ErrorPage");
                    break;
                case 500:
                    routeData.Values.Add("action", "ErrorPage");
                    break;
                case 200:
                    routeData.Values.Add("action", "ErrorPage");
                    break;
                case 201:
                    routeData.Values.Add("action", "ErrorPage");
                    break;
                case 401:
                    routeData.Values.Add("action", "ErrorPage");
                    break;
                case 503:
                    routeData.Values.Add("action", "ErrorPage");
                    break;
                default:
                    routeData.Values.Add("action", "ErrorPage");
                    break;
            }

            routeData.Values.Add("exceptionID", exceptionID);
            routeData.Values.Add("exception", exception);
            routeData.Values.Add("statusCode", ((HttpException)exception).GetHttpCode());

            Server.ClearError();

            Response.TrySkipIisCustomErrors = true;

            IController errorController = new ErrorController();
            errorController.Execute(new RequestContext(
                 new HttpContextWrapper(Context), routeData));
        }
    }

很抱歉让问题这么久。我想确定如何在不让你们知道我做了什么的情况下提出这个问题

由于

2 个答案:

答案 0 :(得分:0)

如果要在具有特定HTTP状态的Web API中引发异常,可以在Web API服务中使用 HttpResponseException

有关详情,请访问http://www.asp.net/web-api/overview/web-api-routing-and-actions/web-api-global-error-handling

答案 1 :(得分:0)

您需要创建新的API异常

using System.Web.Http;
using System.Net.Http;
using System.Net;

throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.NotFound));

枚举列表

    //
    // Summary:
    //     Equivalent to HTTP status 100. System.Net.HttpStatusCode.Continue indicates that
    //     the client can continue with its request.
    Continue = 100,
    //
    // Summary:
    //     Equivalent to HTTP status 101. System.Net.HttpStatusCode.SwitchingProtocols indicates
    //     that the protocol version or protocol is being changed.
    SwitchingProtocols = 101,
    //
    // Summary:
    //     Equivalent to HTTP status 200. System.Net.HttpStatusCode.OK indicates that the
    //     request succeeded and that the requested information is in the response. This
    //     is the most common status code to receive.
    OK = 200,
    //
    // Summary:
    //     Equivalent to HTTP status 201. System.Net.HttpStatusCode.Created indicates that
    //     the request resulted in a new resource created before the response was sent.
    Created = 201,
    //
    // Summary:
    //     Equivalent to HTTP status 202. System.Net.HttpStatusCode.Accepted indicates that
    //     the request has been accepted for further processing.
    Accepted = 202,
    //
    // Summary:
    //     Equivalent to HTTP status 203. System.Net.HttpStatusCode.NonAuthoritativeInformation
    //     indicates that the returned metainformation is from a cached copy instead of
    //     the origin server and therefore may be incorrect.
    NonAuthoritativeInformation = 203,
    //
    // Summary:
    //     Equivalent to HTTP status 204. System.Net.HttpStatusCode.NoContent indicates
    //     that the request has been successfully processed and that the response is intentionally
    //     blank.
    NoContent = 204,
    //
    // Summary:
    //     Equivalent to HTTP status 205. System.Net.HttpStatusCode.ResetContent indicates
    //     that the client should reset (not reload) the current resource.
    ResetContent = 205,
    //
    // Summary:
    //     Equivalent to HTTP status 206. System.Net.HttpStatusCode.PartialContent indicates
    //     that the response is a partial response as requested by a GET request that includes
    //     a byte range.
    PartialContent = 206,
    //
    // Summary:
    //     Equivalent to HTTP status 300. System.Net.HttpStatusCode.MultipleChoices indicates
    //     that the requested information has multiple representations. The default action
    //     is to treat this status as a redirect and follow the contents of the Location
    //     header associated with this response.
    MultipleChoices = 300,
    //
    // Summary:
    //     Equivalent to HTTP status 300. System.Net.HttpStatusCode.Ambiguous indicates
    //     that the requested information has multiple representations. The default action
    //     is to treat this status as a redirect and follow the contents of the Location
    //     header associated with this response.
    Ambiguous = 300,
    //
    // Summary:
    //     Equivalent to HTTP status 301. System.Net.HttpStatusCode.MovedPermanently indicates
    //     that the requested information has been moved to the URI specified in the Location
    //     header. The default action when this status is received is to follow the Location
    //     header associated with the response.
    MovedPermanently = 301,
    //
    // Summary:
    //     Equivalent to HTTP status 301. System.Net.HttpStatusCode.Moved indicates that
    //     the requested information has been moved to the URI specified in the Location
    //     header. The default action when this status is received is to follow the Location
    //     header associated with the response. When the original request method was POST,
    //     the redirected request will use the GET method.
    Moved = 301,
    //
    // Summary:
    //     Equivalent to HTTP status 302. System.Net.HttpStatusCode.Found indicates that
    //     the requested information is located at the URI specified in the Location header.
    //     The default action when this status is received is to follow the Location header
    //     associated with the response. When the original request method was POST, the
    //     redirected request will use the GET method.
    Found = 302,
    //
    // Summary:
    //     Equivalent to HTTP status 302. System.Net.HttpStatusCode.Redirect indicates that
    //     the requested information is located at the URI specified in the Location header.
    //     The default action when this status is received is to follow the Location header
    //     associated with the response. When the original request method was POST, the
    //     redirected request will use the GET method.
    Redirect = 302,
    //
    // Summary:
    //     Equivalent to HTTP status 303. System.Net.HttpStatusCode.SeeOther automatically
    //     redirects the client to the URI specified in the Location header as the result
    //     of a POST. The request to the resource specified by the Location header will
    //     be made with a GET.
    SeeOther = 303,
    //
    // Summary:
    //     Equivalent to HTTP status 303. System.Net.HttpStatusCode.RedirectMethod automatically
    //     redirects the client to the URI specified in the Location header as the result
    //     of a POST. The request to the resource specified by the Location header will
    //     be made with a GET.
    RedirectMethod = 303,
    //
    // Summary:
    //     Equivalent to HTTP status 304. System.Net.HttpStatusCode.NotModified indicates
    //     that the client's cached copy is up to date. The contents of the resource are
    //     not transferred.
    NotModified = 304,
    //
    // Summary:
    //     Equivalent to HTTP status 305. System.Net.HttpStatusCode.UseProxy indicates that
    //     the request should use the proxy server at the URI specified in the Location
    //     header.
    UseProxy = 305,
    //
    // Summary:
    //     Equivalent to HTTP status 306. System.Net.HttpStatusCode.Unused is a proposed
    //     extension to the HTTP/1.1 specification that is not fully specified.
    Unused = 306,
    //
    // Summary:
    //     Equivalent to HTTP status 307. System.Net.HttpStatusCode.TemporaryRedirect indicates
    //     that the request information is located at the URI specified in the Location
    //     header. The default action when this status is received is to follow the Location
    //     header associated with the response. When the original request method was POST,
    //     the redirected request will also use the POST method.
    TemporaryRedirect = 307,
    //
    // Summary:
    //     Equivalent to HTTP status 307. System.Net.HttpStatusCode.RedirectKeepVerb indicates
    //     that the request information is located at the URI specified in the Location
    //     header. The default action when this status is received is to follow the Location
    //     header associated with the response. When the original request method was POST,
    //     the redirected request will also use the POST method.
    RedirectKeepVerb = 307,
    //
    // Summary:
    //     Equivalent to HTTP status 400. System.Net.HttpStatusCode.BadRequest indicates
    //     that the request could not be understood by the server. System.Net.HttpStatusCode.BadRequest
    //     is sent when no other error is applicable, or if the exact error is unknown or
    //     does not have its own error code.
    BadRequest = 400,
    //
    // Summary:
    //     Equivalent to HTTP status 401. System.Net.HttpStatusCode.Unauthorized indicates
    //     that the requested resource requires authentication. The WWW-Authenticate header
    //     contains the details of how to perform the authentication.
    Unauthorized = 401,
    //
    // Summary:
    //     Equivalent to HTTP status 402. System.Net.HttpStatusCode.PaymentRequired is reserved
    //     for future use.
    PaymentRequired = 402,
    //
    // Summary:
    //     Equivalent to HTTP status 403. System.Net.HttpStatusCode.Forbidden indicates
    //     that the server refuses to fulfill the request.
    Forbidden = 403,
    //
    // Summary:
    //     Equivalent to HTTP status 404. System.Net.HttpStatusCode.NotFound indicates that
    //     the requested resource does not exist on the server.
    NotFound = 404,
    //
    // Summary:
    //     Equivalent to HTTP status 405. System.Net.HttpStatusCode.MethodNotAllowed indicates
    //     that the request method (POST or GET) is not allowed on the requested resource.
    MethodNotAllowed = 405,
    //
    // Summary:
    //     Equivalent to HTTP status 406. System.Net.HttpStatusCode.NotAcceptable indicates
    //     that the client has indicated with Accept headers that it will not accept any
    //     of the available representations of the resource.
    NotAcceptable = 406,
    //
    // Summary:
    //     Equivalent to HTTP status 407. System.Net.HttpStatusCode.ProxyAuthenticationRequired
    //     indicates that the requested proxy requires authentication. The Proxy-authenticate
    //     header contains the details of how to perform the authentication.
    ProxyAuthenticationRequired = 407,
    //
    // Summary:
    //     Equivalent to HTTP status 408. System.Net.HttpStatusCode.RequestTimeout indicates
    //     that the client did not send a request within the time the server was expecting
    //     the request.
    RequestTimeout = 408,
    //
    // Summary:
    //     Equivalent to HTTP status 409. System.Net.HttpStatusCode.Conflict indicates that
    //     the request could not be carried out because of a conflict on the server.
    Conflict = 409,
    //
    // Summary:
    //     Equivalent to HTTP status 410. System.Net.HttpStatusCode.Gone indicates that
    //     the requested resource is no longer available.
    Gone = 410,
    //
    // Summary:
    //     Equivalent to HTTP status 411. System.Net.HttpStatusCode.LengthRequired indicates
    //     that the required Content-length header is missing.
    LengthRequired = 411,
    //
    // Summary:
    //     Equivalent to HTTP status 412. System.Net.HttpStatusCode.PreconditionFailed indicates
    //     that a condition set for this request failed, and the request cannot be carried
    //     out. Conditions are set with conditional request headers like If-Match, If-None-Match,
    //     or If-Unmodified-Since.
    PreconditionFailed = 412,
    //
    // Summary:
    //     Equivalent to HTTP status 413. System.Net.HttpStatusCode.RequestEntityTooLarge
    //     indicates that the request is too large for the server to process.
    RequestEntityTooLarge = 413,
    //
    // Summary:
    //     Equivalent to HTTP status 414. System.Net.HttpStatusCode.RequestUriTooLong indicates
    //     that the URI is too long.
    RequestUriTooLong = 414,
    //
    // Summary:
    //     Equivalent to HTTP status 415. System.Net.HttpStatusCode.UnsupportedMediaType
    //     indicates that the request is an unsupported type.
    UnsupportedMediaType = 415,
    //
    // Summary:
    //     Equivalent to HTTP status 416. System.Net.HttpStatusCode.RequestedRangeNotSatisfiable
    //     indicates that the range of data requested from the resource cannot be returned,
    //     either because the beginning of the range is before the beginning of the resource,
    //     or the end of the range is after the end of the resource.
    RequestedRangeNotSatisfiable = 416,
    //
    // Summary:
    //     Equivalent to HTTP status 417. System.Net.HttpStatusCode.ExpectationFailed indicates
    //     that an expectation given in an Expect header could not be met by the server.
    ExpectationFailed = 417,
    //
    // Summary:
    //     Equivalent to HTTP status 426. System.Net.HttpStatusCode.UpgradeRequired indicates
    //     that the client should switch to a different protocol such as TLS/1.0.
    UpgradeRequired = 426,
    //
    // Summary:
    //     Equivalent to HTTP status 500. System.Net.HttpStatusCode.InternalServerError
    //     indicates that a generic error has occurred on the server.
    InternalServerError = 500,
    //
    // Summary:
    //     Equivalent to HTTP status 501. System.Net.HttpStatusCode.NotImplemented indicates
    //     that the server does not support the requested function.
    NotImplemented = 501,
    //
    // Summary:
    //     Equivalent to HTTP status 502. System.Net.HttpStatusCode.BadGateway indicates
    //     that an intermediate proxy server received a bad response from another proxy
    //     or the origin server.
    BadGateway = 502,
    //
    // Summary:
    //     Equivalent to HTTP status 503. System.Net.HttpStatusCode.ServiceUnavailable indicates
    //     that the server is temporarily unavailable, usually due to high load or maintenance.
    ServiceUnavailable = 503,
    //
    // Summary:
    //     Equivalent to HTTP status 504. System.Net.HttpStatusCode.GatewayTimeout indicates
    //     that an intermediate proxy server timed out while waiting for a response from
    //     another proxy or the origin server.
    GatewayTimeout = 504,
    //
    // Summary:
    //     Equivalent to HTTP status 505. System.Net.HttpStatusCode.HttpVersionNotSupported
    //     indicates that the requested HTTP version is not supported by the server.
    HttpVersionNotSupported = 505

HttpStatusCode是一个枚举。只需使用您可能需要的任何财产。