【转】一个ASP.NET MVC中ajax调用WebApi返回500 Internal Server Error的调错方法。
?? ? ?ASP.NET MVC 引入的WebApi自然且較好地滿足了ajax的交互需求,但使用jQuery ajax調(diào)用WebApi返回500 Internal Server Error時(shí)卻不太好查找錯(cuò)誤。在一個(gè)實(shí)際項(xiàng)目中,WebApi方法全部使用了try-catch捕獲異常,并返回定制的錯(cuò)誤消息,想當(dāng)然認(rèn)為有錯(cuò)誤就能捕獲。但最近網(wǎng)站運(yùn)行時(shí)卻總是有500錯(cuò)誤,花了一番功夫才發(fā)現(xiàn)問題所在。
? ? ? ? 經(jīng)過多次調(diào)試,確定這個(gè)錯(cuò)誤應(yīng)該是WebApi方法之外引發(fā)的(方法內(nèi)部應(yīng)該被try-catch捕獲)。初步判斷,是在ASP.NET MVC框架的JSON序列化返回對象時(shí)引發(fā)的一個(gè)運(yùn)行時(shí)錯(cuò)誤。于是,使用Newtonsoft.Json.JsonConvert.SerializeObject()方法序列化待返回的對象就發(fā)現(xiàn)了錯(cuò)誤所在:一個(gè)類對象的get屬性(派生值)中出現(xiàn)被0除的情況。一般而言,對象的get屬性僅僅在訪問該屬性時(shí)才運(yùn)行其中的代碼。顯然,JSON序列化對象時(shí)調(diào)用了對象所有的get屬性代碼并獲得持久屬性值。
? ? ? ?結(jié)論:
?
? ? ??本文介紹的方法在Visual Studio Community 2015、 .NET 4.0和ASP.NET MVC4上調(diào)試通過。
? ? ????后記:
? ? ? 經(jīng)過數(shù)天的網(wǎng)查調(diào)試,找到了一個(gè)通用的、捕獲WebApi方法Json序列化產(chǎn)生異常的方法,基本思路:定制ASP.NET MVC默認(rèn)的Json序列化轉(zhuǎn)換器JsonConverter(該類由Newtonsoft動(dòng)態(tài)庫提供),在讀寫序列化流時(shí)捕獲異常。
? ? ? 重寫的JsonConverter轉(zhuǎn)換器類代碼如下:
using System;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Net.Http.Formatting;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
namespace WebAPI.Common
{
? ? public class JsonConverter: MediaTypeFormatter
? ? {
? ? ? ? private JsonSerializerSettings _jsonSerializerSettings;
? ? ? ? private UTF8Encoding Encoding;
? ? ? ? public JsonConverter(JsonSerializerSettings jsonSerializerSettings)
? ? ? ? {
? ? ? ? ? ? _jsonSerializerSettings = jsonSerializerSettings ?? new JsonSerializerSettings();
? ? ? ? ? ? // Fill out the mediatype and encoding we support
? ? ? ? ? ? SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/json"));
? ? ? ? ? ? Encoding = new UTF8Encoding(false, true);
? ? ? ? }
? ? ? ? public override bool CanReadType(Type type)
? ? ? ? {
? ? ? ? ? ? //if (type == typeof(IKeyValueModel))
? ? ? ? ? ? //{
? ? ? ? ? ? // ? ?return false;
? ? ? ? ? ? //}
? ? ? ? ? ? return true;
? ? ? ? }
? ? ? ? public override bool CanWriteType(Type type)
? ? ? ? {
? ? ? ? ? ? return true;
? ? ? ? }
? ? ? ? public override Task<object> ReadFromStreamAsync(Type type, Stream readStream, HttpContent content, IFormatterLogger formatterLogger)
? ? ? ? {
? ? ? ? ? ? // Create a serializer
? ? ? ? ? ? JsonSerializer serializer = JsonSerializer.Create(_jsonSerializerSettings);
? ? ? ? ? ? // Create task reading the content
? ? ? ? ? ? return Task.Factory.StartNew(() =>
? ? ? ? ? ? {
? ? ? ? ? ? ? ? using (StreamReader streamReader = new StreamReader(readStream, Encoding))
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? using (JsonTextReader jsonTextReader = new JsonTextReader(streamReader))
? ? ? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? ? ? return serializer.Deserialize(jsonTextReader, type);
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? }
? ? ? ? ? ? });
? ? ? ? }
? ? ? ? public override Task WriteToStreamAsync(Type type, object value, Stream writeStream, HttpContent content, TransportContext transportContext)
? ? ? ? {
? ? ? ? ? ? // Create a serializer
? ? ? ? ? ? JsonSerializer serializer = JsonSerializer.Create(_jsonSerializerSettings);
? ? ? ? ? ? // Create task writing the serialized content
? ? ? ? ? ? return Task.Factory.StartNew(() =>
? ? ? ? ? ? {
? ? ? ? ? ? ? ? using (StreamWriter streamWriter = new StreamWriter(writeStream, Encoding))
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? using (JsonTextWriter jsonTextWriter = new JsonTextWriter(streamWriter))
? ? ? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? ? ? serializer.Serialize(jsonTextWriter, value);
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? }
? ? ? ? ? ? });
? ? ? ? }
? ? }
}
總結(jié)
以上是生活随笔為你收集整理的【转】一个ASP.NET MVC中ajax调用WebApi返回500 Internal Server Error的调错方法。的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【转】一键将Web应用发布到云-Azur
- 下一篇: 【转】.NET程序内存分析工具CLRPr