Dynamics CRM2016 解决C#调用web api报错无法显示错误详情的问题
2017-07-14 15:48
495 查看
在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
}
} 最后感谢路人甲提供的参考代码。
先来看下普通的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
}
} 最后感谢路人甲提供的参考代码。
相关文章推荐
- 解决Android调用系统相机拍照后相片无法在相册中显示问题
- 解决调用本地时间做的时间显示中可能出现的时间调用错误的问题
- C# 调用 C++ DLL无法调试的问题解决方法
- MATLAB在调用C/C++程序成功,使用opencv库时出错,错误显示“找不到指定模块”(问题未解决)
- c# 调用log4net,解决中文字符显示乱码的问题
- 解决webapp中使用cordova调用本地相册,在ios设备上无法显示图片的问题
- api 详情页面无法显示的问题如何解决
- ruby -- 问题解决(三)编码错误导致无法显示(1)
- ruby -- 问题解决(四)编码错误导致无法显示(2)
- C# 解决调用winform窗体顶置且解决任务栏图片显示问题
- 解决在Win7下使用schtasks命令显示 “错误:无法加载列表资源” 的问题
- C#技巧【调用线程无法访问此对象,因为另一个线程拥有该对象的问题的解决办法】【C#读写EXCEL源码提示“office检测到此文件存在一个问题。为帮助保护您的计算机,不能打开此文件”的解决】
- ThinkPHP3出现“页面无法显示”的330错误问题解决
- 浏览器无法显示某些网页或者提示脚本错误的问题解决
- 解决 fedora 5 root 用户 vi 无法高亮显示问题
- ASP.NET调用Oracle组件提示无法装载DLL(oci.dll)错误的解决办法
- NET中"无法显示 XML 页。 使用 XSL 样式表无法查看 XML 输入。"问题的解决
- 重新安装IIS后打开报表管理器出现“无法显示 XML 页”错误的解决办法。
- oracle中解决汉字无法显示、输入问题
- Vs.net C# 中断点无法命中问题的解决