58

クライアントが適切なアクションを実行できるように、このリンクでアドバイスされているように、コントローラーへの呼び出しにエラーを返そうとしました 。コントローラーは、jquery AJAX を介して JavaScript によって呼び出されます。ステータスをエラーに設定しない場合にのみ、Json オブジェクトを取得しています。サンプルコードはこちら

if (response.errors.Length > 0)
   Response.StatusCode = (int)HttpStatusCode.BadRequest;
return Json(response);

ステータスコードを設定しない場合、Json を取得します。ステータス コードを設定すると、ステータス コードは返されますが、Json エラー オブジェクトは返されません。

更新 ajax のエラーコールバックを処理できるように、エラーオブジェクトを JSON として送信したいと考えています。

4

13 に答える 13

42

ここで解決策を見つけました

MVC のデフォルトの動作をオーバーライドするには、アクション フィルターを作成する必要がありました

ここに私の例外クラスがあります

class ValidationException : ApplicationException
{
    public JsonResult exceptionDetails;
    public ValidationException(JsonResult exceptionDetails)
    {
        this.exceptionDetails = exceptionDetails;
    }
    public ValidationException(string message) : base(message) { }
    public ValidationException(string message, Exception inner) : base(message, inner) { }
    protected ValidationException(
    System.Runtime.Serialization.SerializationInfo info,
    System.Runtime.Serialization.StreamingContext context)
        : base(info, context) { }
}

JSON を初期化するコンストラクターがあることに注意してください。アクションフィルターはこちら

public class HandleUIExceptionAttribute : FilterAttribute, IExceptionFilter
{
    public virtual void OnException(ExceptionContext filterContext)
    {
        if (filterContext == null)
        {
            throw new ArgumentNullException("filterContext");
        }
        if (filterContext.Exception != null)
        {
            filterContext.ExceptionHandled = true;
            filterContext.HttpContext.Response.Clear();
            filterContext.HttpContext.Response.TrySkipIisCustomErrors = true;
            filterContext.HttpContext.Response.StatusCode = (int)System.Net.HttpStatusCode.InternalServerError;
            filterContext.Result = ((ValidationException)filterContext.Exception).myJsonError;
        }
    }

アクション フィルターができたので、コントローラーをフィルター属性で装飾します。

[HandleUIException]
public JsonResult UpdateName(string objectToUpdate)
{
   var response = myClient.ValidateObject(objectToUpdate);
   if (response.errors.Length > 0)
     throw new ValidationException(Json(response));
}

エラーがスローされると、IExceptionFilter を実装するアクション フィルターが呼び出され、エラー コールバックでクライアントに Json が返されます。

于 2012-07-12T00:36:57.583 に答える
30

この問題には非常に洗練された解決策があります。web.config を使用してサイトを構成するだけです。

<system.webServer>
    <httpErrors errorMode="DetailedLocalOnly" existingResponse="PassThrough"/>
</system.webServer>

ソース: https://serverfault.com/questions/123729/iis-is-overriding-my-response-content-if-i-manually-set-the-response-statuscode

于 2013-06-20T08:20:59.977 に答える
10

Richard Garside からの回答に基づいて、ASP.Net Core バージョンを次に示します。

public class JsonErrorResult : JsonResult
{
    private readonly HttpStatusCode _statusCode;

    public JsonErrorResult(object json) : this(json, HttpStatusCode.InternalServerError)
    {
    }

    public JsonErrorResult(object json, HttpStatusCode statusCode) : base(json)
    {
        _statusCode = statusCode;
    }

    public override void ExecuteResult(ActionContext context)
    {
        context.HttpContext.Response.StatusCode = (int)_statusCode;
        base.ExecuteResult(context);
    }

    public override Task ExecuteResultAsync(ActionContext context)
    {
        context.HttpContext.Response.StatusCode = (int)_statusCode;
        return base.ExecuteResultAsync(context);
    }
}

次に、コントローラーで次のように返します。

// Set a json object to return. The status code defaults to 500
return new JsonErrorResult(new { message = "Sorry, an internal error occurred."});

// Or you can override the status code
return new JsonErrorResult(new { foo = "bar"}, HttpStatusCode.NotFound);
于 2017-05-04T13:38:37.340 に答える
5

StatusCode を設定した後、JSON エラー オブジェクトを自分で返す必要があります。

if (BadRequest)
{
    Dictionary<string, object> error = new Dictionary<string, object>();
    error.Add("ErrorCode", -1);
    error.Add("ErrorMessage", "Something really bad happened");
    return Json(error);
}

もう 1 つの方法はJsonErrorModel

public class JsonErrorModel
{
    public int ErrorCode { get; set;}

    public string ErrorMessage { get; set; }
}

public ActionResult SomeMethod()
{

    if (BadRequest)
    {
        var error = new JsonErrorModel
        {
            ErrorCode = -1,
            ErrorMessage = "Something really bad happened"
        };

        return Json(error);
    }

   //Return valid response
}

こちらの回答も参考にしてください

于 2012-07-06T22:38:22.930 に答える
4

「HTTP レベル エラー」(エラー コードの目的) または「アプリケーション レベル エラー」(カスタム JSON 応答の目的) のどちらが必要かを決定する必要があります。

エラー コードが 2xx (成功範囲) 以外に設定されている場合、HTTP を使用するほとんどの高レベル オブジェクトは応答ストリームを調べません。あなたの場合、明示的にエラー コードを失敗 (403 または 500 だと思います) に設定し、XMLHttp オブジェクトに応答の本文を無視させます。

修正するには、クライアント側でエラー条件を処理するか、エラー コードを設定せずにエラー情報を含む JSON を返します (詳細については、Sbossb 応答を参照してください)。

于 2012-07-06T22:41:48.003 に答える
3

あなたのニーズが Sarath のものほど複雑でない場合は、もっと単純なもので済ませることができます:

[MyError]
public JsonResult Error(string objectToUpdate)
{
   throw new Exception("ERROR!");
}

public class MyErrorAttribute : FilterAttribute, IExceptionFilter
{
   public virtual void OnException(ExceptionContext filterContext)
   {
      if (filterContext == null)
      {
         throw new ArgumentNullException("filterContext");
      }
      if (filterContext.Exception != null)
      {
         filterContext.ExceptionHandled = true;
         filterContext.HttpContext.Response.Clear();
         filterContext.HttpContext.Response.TrySkipIisCustomErrors = true;
         filterContext.HttpContext.Response.StatusCode = (int)System.Net.HttpStatusCode.InternalServerError;
         filterContext.Result = new JsonResult() { Data = filterContext.Exception.Message };
      }
   }
}
于 2013-08-04T17:43:09.040 に答える