jQuery 1.11.3发布收到错误请求但不会失败

时间:2016-08-02 07:41:08

标签: c# jquery asp.net-mvc umbraco

jQuery 1.11.3 Post从HttpResponseMessage接收Bad Request但不会失败。来自服务器的消息是以下字符串:

  

" StatusCode:400,ReasonPhrase:'错误请求',版本:1.1,内容:   ,标题:{}"

我是否应该从HttpResponseMessage中获取一个说错误请求的对象?我正在使用IIS Express。

Bad request

后端:

[HttpPost]
public HttpResponseMessage DeleteOrderRow(int orderRowId)
{
    var row = OrderRowData.LoadItem(orderRowId);
    if (row == null)
    {
        AddAlert(AlertStyles.Danger, "Order row does not exist");
        //Below is the example being returned
        return new HttpResponseMessage(HttpStatusCode.BadRequest);
    }
    OrderRowData.Delete(orderRowId);
    AddAlert(AlertStyles.Success, "Order row has been removed");
    return new HttpResponseMessage(HttpStatusCode.OK);
}

jQuery的:

$(document).on('click', '.delete-order-row', function (event) {
    event.preventDefault();

    var element = $(this);
    var id = element.data('id');

    if (id == null || id === -1) {
        element.closest('tr').remove();
    } else {
        var url = element.attr('href');
        $.post(url, { orderRowId: id })
            .done(function (data) {
                element.closest('tr').remove();
            })
            .fail(function (xhr, status, error) {
                location.reload();
            });
    }
});

更新:@smoksnes提示后检查网络连接。即使从后端发送return new HttpResponseMessage(HttpStatusCode.BadRequest);,服务器实际上也会发送200 OK。这是IIS Express的正常行为吗?

Network tab

更新2:使用此代码解决了客户端问题。根据@smoksnes的回复,IExceptionFilterExceptionFilterAttribute在我的项目中不存在,我怀疑Umbraco。还有其他人在Umbraco经历过这个吗?

.done(function (data) {
    if (data.indexOf("StatusCode: 400") !== -1) {
        $(window).scrollTop(0);
        location.reload();
    } else {
        element.closest('tr').remove();
    }
})

3 个答案:

答案 0 :(得分:1)

  

这是IIS Express的正常行为吗?

在空白项目中,这应该返回400 Bad Request

400 Bad Request

public HttpResponseMessage DeleteOrderRow()
{
    return new HttpResponseMessage(HttpStatusCode.BadRequest);
}

但正如我在评论中提到的,您似乎根据网络标签中的信息获得了200 OK。这就是导致客户端脚本输入done()的原因。这可能是由自定义过滤器引起的。

检查项目中的IExceptionFilterExceptionFilterAttribute

一个常见的解决方案是在Gobal.asax中添加这些过滤器:

FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);


public class FilterConfig
{
    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
        filters.Add(new HandleErrorAttribute()); // Or whatever filter you got.
        filters.Add(new AjaxExceptionLoggingFilter());
    }
}

他们可以将回复更改为200 OK

此外,根据网址,您似乎正在使用Umbraco。我对它不是很熟悉,但那里可能会有一些魔力。如果你无法在服务器端解决它,你可以在客户端解决它:

   //Quick fix (dirty)
   $.post(url, { orderRowId: id })
        .done(function (data) {
            if(data.StatusCode != 200)
            {
                // do error stuff..
                return;
            }
            element.closest('tr').remove();
        })
        .fail(function (xhr, status, error) {
            location.reload();
        });

ajaxPrefilter

// Written by hand and not tested.
$.ajaxPrefilter(function(options, originalOptions, jqXHR) {
    var success = options.success;
    options.success = function(data, textStatus, jqXHR) {
        // override success handling
        if(data && data.StatusCode != 200)
        {
            // Go to error.
            return options.error(data);
        }
        else if(typeof(success) === "function") return success(data, textStatus, jqXHR);
    };
    var error = options.error;
    options.error = function(jqXHR, textStatus, errorThrown) {
        // override error handling
        if(typeof(error) === "function") return error(jqXHR, textStatus, errorThrown);
    };
});

或延期:

$.ajaxPrefilter(function(opts, originalOpts, jqXHR) {
    // you could pass this option in on a "retry" so that it doesn't
    // get all recursive on you.
    if ( opts.retryAttempt ) {
        return;
    }

    var dfd = $.Deferred();

    // if the request works, return normally
    jqXHR.done(function(result){
        // Maybe check for result != null?
        if(result.StatusCode != 200) {
            dfd.reject() // Manually reject
        }
        else {
            dfd.resolve(result);
        }

    });

    jqXHR.fail(dfd.reject);

    // NOW override the jqXHR's promise functions with our deferred
    return dfd.promise(jqXHR);
});

可以找到ajaxPrefilter的更完整示例here

答案 1 :(得分:0)

我认为问题是你每次都返回一个HttpResponseMessage ,你应该抛出一个响应异常:

var resp = new HttpResponseMessage(HttpStatusCode.BadRequest);
throw new HttpResponseException(resp);

答案 2 :(得分:0)

使用此代码解决了客户端问题。根据@smoksnes的回复,IExceptionFilterExceptionFilterAttribute在我的项目中不存在,我怀疑Umbraco。

.done(function (data) {
    if (data.indexOf("StatusCode: 400") !== -1) {
        $(window).scrollTop(0);
        location.reload();
    } else {
        element.closest('tr').remove();
    }
})