在之前介紹客制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物件沒有傳送回來。
問題原因
可以看到在正式機器,本來要回傳的json資料沒有回傳回來,只出現錯誤的請求
。光這樣看,一時之間還看不出問題。
如果把錯誤的請求
翻譯成英文其實就是 Bad Request
。這個詞就熟悉多了,不就是http 錯誤碼400的描述文字。
這個時候我的直覺就是,會不會和Asp .Net的客制錯誤訊息頁(CustomError)有沒有關係?
解決辦法
最後查到一篇SO,的確可能是IIS的Custom Error介入導致,這個時候,其實解決方法就簡單了,就是想辦法不要讓IIS介入就好。
有兩種解決方法:
- 在Web.config設定
- 在程式裏面處理
在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大部份都 可以找到結果。
沒有留言 :
張貼留言