我有点卡住,我正在尝试创建一个将XML内容发布到Web服务的UWP应用程序。我可以在常规.net控制台应用程序中使用它而不会出现问题。试图使用UWP重新创建它被证明是棘手的。使用fiddler我已经缩小了Web服务端点没有收到我的内容。看起来标题设置正确,内容长度正确发送但实际内容未发送。这是代码的核心,它在以下情况下崩溃/抛出异常:
HttpResponseMessage ResponseMessage = await request.PostAsync(requestUri, httpContent2).ContinueWith(
(postTask) => postTask.Result.EnsureSuccessStatusCode());
当我尝试执行PostASync时,看着fiddler,我得到了:
HTTP/1.1 408 Request body incomplete
Date: Mon, 14 Nov 2016 15:38:53 GMT
Content-Type: text/html; charset=UTF-8
Connection: close
Cache-Control: no-cache, must-revalidate
Timestamp: 10:38:53.430
请求正文不包含指定的字节数。得到0,预计617
我很肯定我正在获取内容以便发布正确(我从文件中读取它,我将其发送到调试窗口以验证它是否正确)。我认为它可能与HttpContent httpContent2有关 - 在常规.NET中我从来不需要使用它,但使用PostAsync我需要使用它。
任何想法都将不胜感激,谢谢!
public async void PostWebService()
{
string filePath = "Data\\postbody.txt";
string url = "https://outlook.office365.com/EWS/Exchange.asmx";
Uri requestUri = new Uri(url); //replace your Url
var myClientHandler = new HttpClientHandler();
myClientHandler.Credentials = new NetworkCredential("user@acme.com", "password");
HttpClient request = new HttpClient(myClientHandler);
string contents = await ReadFileContentsAsync(filePath);
Debug.WriteLine(contents);
HttpContent httpContent2 = new StringContent(contents, Encoding.UTF8, "text/xml");
string s = await httpContent2.ReadAsStringAsync();
Debug.WriteLine(s); //just checking to see if httpContent has the correct data
//HttpResponseMessage ResponseMessage = await request.PostAsync(requestUri, httpContent);
request.MaxResponseContentBufferSize = 65000;
HttpResponseMessage ResponseMessage = await request.PostAsync(requestUri, httpContent2).ContinueWith(
(postTask) => postTask.Result.EnsureSuccessStatusCode());
Debug.WriteLine(ResponseMessage.ToString());
}
答案 0 :(得分:2)
好像我找到了问题的根本原因。使用网络身份验证时,这似乎是System.Net.Http.HttpClient的已知错误。请参阅此文here
我最初的错误是我没有抓住PostAsync抛出的异常。一旦我把它包装在try / catch块中,我就抛出了以下异常:
“此IRandomAccessStream不支持GetInputStreamAt方法,因为它需要克隆,此流不支持克隆。”
我上面链接的文章的第一段说明:
当您使用.NET中的System.Net.Http.HttpClient类时 基于框架的通用Windows平台(UWP)应用程序并发送 HTTP(s)对需要集成Windows的URI的PUT或POST请求 身份验证 - 例如Negotiate / NTLM,将抛出异常。
抛出的异常将InnerException属性设置为 消息:
“此IRandomAccessStream不支持GetInputStreamAt方法 因为它需要克隆,而且这个流不支持克隆。“
问题发生的原因是请求以及实体主体 在身份验证期间需要重新提交POST / PUT请求 挑战。对于HTTP动词,例如,上述问题不会发生 GET不需要实体。
这是Windows 10 SDK的RTM版本中的一个已知问题 正在为后续版本跟踪此问题的修复程序。
对我有用的建议和解决方法是使用 Windows.Web.Http.HttpClient 而不是 System.Net.Http.HttpClient
使用该建议,以下代码对我有用:
string filePath = "Data\\postbody.txt";
string url = "https://outlook.office365.com/EWS/Exchange.asmx";
Uri requestUri = new Uri(url); //replace your Url
string contents = await ReadFileContentsAsync(filePath);
string search_str = txtSearch.Text;
Debug.WriteLine("Search query:" + search_str);
contents = contents.Replace("%SEARCH%", search_str);
Windows.Web.Http.Filters.HttpBaseProtocolFilter hbpf = new Windows.Web.Http.Filters.HttpBaseProtocolFilter();
Windows.Security.Credentials.PasswordCredential pcred = new Windows.Security.Credentials.PasswordCredential(url, "username@acme.com", "password");
hbpf.ServerCredential = pcred;
HttpClient request = new HttpClient(hbpf);
Windows.Web.Http.HttpRequestMessage hreqm = new Windows.Web.Http.HttpRequestMessage(Windows.Web.Http.HttpMethod.Post, new Uri(url));
Windows.Web.Http.HttpStringContent hstr = new Windows.Web.Http.HttpStringContent(contents, Windows.Storage.Streams.UnicodeEncoding.Utf8, "text/xml");
hreqm.Content = hstr;
// consume the HttpResponseMessage and the remainder of your code logic from here.
try
{
Windows.Web.Http.HttpResponseMessage hrespm = await request.SendRequestAsync(hreqm);
Debug.WriteLine(hrespm.Content);
String respcontent = await hrespm.Content.ReadAsStringAsync();
}
catch (Exception ex)
{
string e = ex.Message;
Debug.WriteLine(e);
}
希望这有助于遇到此问题的其他人。