Dynamics CRM2016 解決C#呼叫web api報錯無法顯示錯誤詳情的問題
在js中呼叫web api如果報錯,比如400 bad request,比如500都會在response中看到具體的錯誤,方便我們及時修正,但是在c#中通過httpwebrequest呼叫報錯是看不到的,所以往往需要我們把url拷出來在瀏覽器裡檢視,甚至需要藉助第三方工具來檢視非get請求類的錯誤,還是比較麻煩的。
先來看下普通的httprequest方式報錯返回是什麼樣的,示例程式碼很簡單,建立一條name為DTCC的account記錄
HttpWebRequest req = (HttpWebRequest)HttpWebRequest.
Create("http://121.40.75.24:5555/origin/api/data/v8.0/accounts");
req.Credentials = new NetworkCredential(username, pwd, domain);
req.Method = "post";
req.Accept = "application/json";
req.ContentType = "application/json; charset=utf-8";
byte[] data = Encoding.UTF8.GetBytes("{\"name\":\"DTCC\"}");
Stream newStream = req.GetRequestStream();
newStream.Write(data, 0, data.Length);
newStream.Close();
using (HttpWebResponse res = (HttpWebResponse)req.GetResponse())
{
StreamReader read = new StreamReader(res.GetResponseStream());
string result = read.ReadToEnd();
}
因為我寫了個create的pre外掛阻止了建立,所以這塊提示是500錯,但看不到具體的錯誤原因
我們們來換一種方式,示例程式碼如下
public static async Task Demo_API_02()
{
HttpClientHandler sHandler = new HttpClientHandler();
sHandler.Credentials = new NetworkCredential(username, pwd, domain);
using (var client = new HttpClient(sHandler))
{
client.BaseAddress = new Uri("http://121.40.75.24:5555/origin/api/data/v8.0/accounts");
client.DefaultRequestHeaders.Accept.Clear();
HttpRequestMessage createRequest2 = new HttpRequestMessage(HttpMethod.Post, "");
client.DefaultRequestHeaders.Add("ContentType", "application/json; charset=utf-8");
client.DefaultRequestHeaders.Add("OData-MaxVersion", "4.0");
client.DefaultRequestHeaders.Add("OData-Version", "4.0");
createRequest2.Content = new StringContent("{\"name\":\"DTCC\"}", Encoding.UTF8, "application/json");
HttpResponseMessage createResponse2 = await client.SendAsync(createRequest2);
if (createResponse2.StatusCode == HttpStatusCode.NoContent)
{
var demoUri = createResponse2.Headers.GetValues("OData-EntityId").FirstOrDefault();
}
else
{
var exception = new CrmHttpResponseException(createResponse2.Content);
}
}
}
看下結果,準確的抓到了我外掛中丟擲的exception錯
示例程式碼中用到的CrmHttpResponseException類程式碼如下
public class CrmHttpResponseException : System.Exception
{
#region Properties
private static string _stackTrace;
/// <summary>
/// Gets a string representation of the immediate frames on the call stack.
/// </summary>
public override string StackTrace
{
get { return _stackTrace; }
}
#endregion Properties
#region Constructors
/// <summary>
/// Initializes a new instance of the CrmHttpResponseException class.
/// </summary>
/// <param name="content">The populated HTTP content in Json format.</param>
public CrmHttpResponseException(HttpContent content) : base(ExtractMessageFromContent(content)) { }
/// <summary>
/// Initializes a new instance of the CrmHttpResponseException class.
/// </summary>
/// <param name="content">The populated HTTP content in Json format.</param>
/// <param name="innerexception">The exception that is the cause of the current exception,or a null reference
/// if no innerexception is specified.</param>
public CrmHttpResponseException(HttpContent content, Exception innerexception) : base(ExtractMessageFromContent(content), innerexception) { }
#endregion Constructors
#region Methods
/// <summary>
/// Extracts the CRM specific error message and stack trace from an HTTP content.
/// </summary>
/// <param name="content">The HTTP content in Json format.</param>
/// <returns>The error message.</returns>
private static string ExtractMessageFromContent(HttpContent content)
{
string message = String.Empty;
string downloadedContent = content.ReadAsStringAsync().Result;
if (content.Headers.ContentType.MediaType.Equals("text/plain"))
{
message = downloadedContent;
}
else if (content.Headers.ContentType.MediaType.Equals("application/json"))
{
JObject jcontent = (JObject)JsonConvert.DeserializeObject(downloadedContent);
IDictionary<string, JToken> d = jcontent;
// An error message is returned in the content under the 'error' key.
if (d.ContainsKey("error"))
{
JObject error = (JObject)jcontent.Property("error").Value;
message = (String)error.Property("message").Value;
}
else if (d.ContainsKey("Message"))
message = (String)jcontent.Property("Message").Value;
if (d.ContainsKey("StackTrace"))
_stackTrace = (String)jcontent.Property("StackTrace").Value;
}
else if (content.Headers.ContentType.MediaType.Equals("text/html"))
{
message = "HTML content that was returned is shown below.";
message += "\n\n" + downloadedContent;
}
else
{
message = String.Format("No handler is available for content in the {0} format.", content.Headers.ContentType.MediaType.ToString());
}
return message;
#endregion Methods
}
}
最後感謝路人甲提供的參考程式碼。相關文章
- unity player 顯示播放錯誤時的解決辦法Unity
- 解決codeblocks無法除錯的問題BloC除錯
- ClamAV無法更新錯誤解決
- 解決TOAD中執行計劃顯示報錯的問題
- 使用API28報錯問題及解決API
- 解決windows8無法全屏顯示的問題Windows
- 成功解決github無法顯示圖片問題Github
- 解決VisualStudio無法除錯的問題除錯
- solrcloud頁面顯示報錯Cannot load analyzer問題的解決方法SolrCloud
- Dynamics 365 自定義工作流使用Plugin Registration Tool Profiler除錯時無法顯示Steps的問題Plugin除錯
- 解決 ngrok 的 Domain 錯誤問題AI
- 執行無法解決的編譯錯誤編譯
- Dynamics CRM2016 plugin註冊step時報Assembly file name is in invalid format錯的解決辦法PluginORM
- AD9中元件無法顯示的問題解決元件
- 解決RAW在SQLPLUS上無法顯示的問題SQL
- 微信支付錯誤兩個問題的解決:curl出錯,錯誤碼:60
- 解決chrome,下載在資料夾中顯示,呼叫錯誤的關聯程式Chrome
- Winform無法載入基類的錯誤解決ORM
- RedisTemplate呼叫increment報錯問題RedisREM
- Steam錯誤程式碼138怎麼辦?無法訪問社群提示138錯誤解決方法
- 解決 Inkscape 報錯 Duplicate 問題
- WordPress中文標題無法顯示的解決方法
- 解決下載的CHM檔案無法顯示網頁問題網頁
- Windows無法顯示隱藏資料夾之問題解決Windows
- Win10 tensorflow object_detection api 安裝中 無法顯示影象的問題解決Win10ObjectAPI
- 設定autotrace的報錯問題解決
- 無法顯示頁面,因為發生內部程式錯誤
- dns錯誤怎麼辦 dns錯誤的解決辦法DNS
- command 'gcc' failed with exit status 1錯誤問題的解決辦法GCAI
- 解決WordPress無法顯示已安裝主題的辦法
- tail +數字 無法開啟錯誤解決(ubutu)AI
- PHP顯示全部錯誤PHP
- dbfread報錯ValueError錯誤解決方法Error
- vue 專案引入字型圖示報錯、不顯示等問題Vue
- 徹底解決pidgin群顯示null問題及無法輸入中文的問題Null
- win10系統提示無法顯示當前所有者錯誤如何解決Win10
- dbua後資料庫無法啟動錯誤的解決資料庫
- win7_iis報500.19和500.21錯誤問題解決Win7