Alan Tsai 的學習筆記


學而不思則罔,思而不學則殆,不思不學則“網貸” 為現任微軟最有價值專家 (MVP)、微軟認證講師 (MCT) 、Blogger、Youtuber:記錄軟體開發的點點滴滴 著重於微軟技術、C#、ASP .NET、Azure、DevOps、Docker、AI、Chatbot、Data Science

[Asp .Net Mvc]http status 400 的JsonResult在正式機器無法取得回傳的Json資料

2016-03-03 Thursday

在之前介紹客制JsonResult的時候([iThome 第七屆鐵人賽 28] Javascript和Mvc溝通 - 概念篇[iThome 第七屆鐵人賽 29] Javascript和Mvc溝通 - 實作篇),其中一個原因是爲了讓回傳的資訊可以利用http裏面的狀態碼(status code)設定為400來表示Json結果是錯誤, 然後前端接到的時候可以直接透過在error事件的function來處理有出錯的邏輯。而不是要在success function裏面透過回傳的json物件來判斷是否有成功。

在實際使用的時候,開發都沒有什麽問題,但是在正式機器的時候出現bug,會導致沒有辦法取得回傳的Json物件內容

這篇將會介紹發生的原因和如何處理。

問題描述

在我實際使用上面,在開發階段,return JsonError(),的確會回傳並且狀態是400(因此前端會進入error的function),並且json物件也有回傳回來。

但是在正式機器並非如此。在正式機器,也一樣會回傳400(所以也會進入error的function),但是json物件沒有傳送回來

從下面兩張截圖可以看到,正式機器和測試機器所回傳的內容: 測試機器的Request - 可以看到json資料有回傳回來

測試機器的Request - 可以看到json資料有回傳回來正式機器的Request - 可以看到json資料沒有回來

正式機器的Request - 可以看到json資料沒有回來

問題原因

可以看到在正式機器,本來要回傳的json資料沒有回傳回來,只出現錯誤的請求。光這樣看,一時之間還看不出問題。

如果把錯誤的請求翻譯成英文其實就是 Bad Request。這個詞就熟悉多了,不就是http 錯誤碼400的描述文字。

這個時候我的直覺就是,會不會和Asp .Net的客制錯誤訊息頁(CustomError)有沒有關係?

解決辦法

最後查到一篇SO,的確可能是IIS的Custom Error介入導致,這個時候,其實解決方法就簡單了,就是想辦法不要讓IIS介入就好。

有兩種解決方法:

  1. 在Web.config設定
  2. 在程式裏面處理

在Web.config設定

只需要在Web.config裏面放入:

    ...
    
    ...
web.config的好處是全域都有效果,但是有可能只是部份想要有這個效果,這個時候程式面的設定方法就會比較好。

在程式裏面設定

只要在程式裏面有呼叫:

Response.TrySkipIisCustomErrors = true;
即可。

修正之前客制的JsonResult

知道了解決方法之後,我們就可以針對之前程式碼的部份,在回傳之前加入Response.TrySkipIisCustomErrors = true; 即可:

protected virtual void SerializeData(HttpResponseBase response)
{
    if (ErrorMessages.Any())
    {
        var originalData = Data;
        Data = new
        {
            Success = false,
            OriginalData = originalData,
            ErrorMessage = string.Join("\n", ErrorMessages),
            ErrorMessages = ErrorMessages.ToArray()
        };
 
        response.StatusCode = 400;
        response.TrySkipIisCustomErrors = true;
    }
 
    var settings = new JsonSerializerSettings
    {
        ContractResolver = new CamelCasePropertyNamesContractResolver(),
 
        Converters = new JsonConverter[]
        {
            new StringEnumConverter(), 
        }
    };
 
    response.Write(JsonConvert.SerializeObject(Data, settings));
}

結語

有時候寫code真的要特別小心,尤其是這種正式機器才會發生的問題。不過好在,只要能夠抓到關鍵字,直接google大部份都 可以找到結果。


如果文章對您有幫助,就請我喝杯飲料吧
街口支付QR Code
街口支付QR Code
台灣 Pay QR Code
台灣 Pay QR Code
Line Pay 一卡通 QR Code
Line Pay 一卡通 QR Code
街口支付QR Code
支付寶QR Code
街口支付QR Code
微信支付QR Code
2016-03-03 Thursday
comments powered by Disqus