我在Web上看到了大量使用新HttpClient对象(作为新Web API的一部分)的示例,应该有HttpContent.ReadAsAsync<T>方法.但是,MSDN没有提到这种方法,IntelliSense也没有找到它.
它去了哪里,我该如何解决它?
public static async Task<string> GetData(string url, string data)
{
UriBuilder fullUri = new UriBuilder(url);
if (!string.IsNullOrEmpty(data))
fullUri.Query = data;
HttpClient client = new HttpClient();
HttpResponseMessage response = await client.PostAsync(new Uri(url), /*expects HttpContent*/);
response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
response.EnsureSuccessStatusCode();
string responseBody = await response.Content.ReadAsStringAsync();
return responseBody;
}
Run Code Online (Sandbox Code Playgroud)
将PostAsync采取一个需要另一个参数HttpContent.
我该如何设置HttpContent?任何适用于Windows Phone 8的文档都没有.
如果我这样做GetAsync,那就太棒了!但它需要POST的内容为key ="bla",某事="yay"
//编辑
非常感谢答案......这很有效,但这里还有一些不确定的地方:
public static async Task<string> GetData(string url, string data)
{
data = "test=something";
HttpClient client = new HttpClient();
StringContent queryString …Run Code Online (Sandbox Code Playgroud) 如何在MVC webApi控制器操作中读取PUT请求中的内容.
[HttpPut]
public HttpResponseMessage Put(int accountId, Contact contact)
{
var httpContent = Request.Content;
var asyncContent = httpContent.ReadAsStringAsync().Result;
...
Run Code Online (Sandbox Code Playgroud)
我在这里得到空字符串:(
我需要做的是:弄清楚在初始请求中修改/发送了什么属性(意味着如果Contact对象有10个属性,并且我只想更新其中2个属性,我只发送和对象只有两个属性,这样的事情:
{
"FirstName": null,
"LastName": null,
"id": 21
}
Run Code Online (Sandbox Code Playgroud)
预期的最终结果是
List<string> modified_properties = {"FirstName", "LastName"}
Run Code Online (Sandbox Code Playgroud) 我正在构建一个给出HttpContent对象的函数,它将发出请求并在失败时重试.但是我得到异常,说HttpContent对象在发出请求后被处理掉.无论如何都要复制或复制HttpContent对象,以便我可以发出多个请求.
public HttpResponseMessage ExecuteWithRetry(string url, HttpContent content)
{
HttpResponseMessage result = null;
bool success = false;
do
{
using (var client = new HttpClient())
{
result = client.PostAsync(url, content).Result;
success = result.IsSuccessStatusCode;
}
}
while (!success);
return result;
}
// Works with no exception if first request is successful
ExecuteWithRetry("http://www.requestb.in/xfxcva" /*valid url*/, new StringContent("Hello World"));
// Throws if request has to be retried ...
ExecuteWithRetry("http://www.requestb.in/badurl" /*invalid url*/, new StringContent("Hello World"));
Run Code Online (Sandbox Code Playgroud)
(显然我不会无限期地尝试,但上面的代码基本上就是我想要的).
它产生了这个例外
System.AggregateException: One or more errors occurred. ---> System.ObjectDisposedException: …Run Code Online (Sandbox Code Playgroud) 所以,我创建了一个HttpClient并使用发布数据HttpClient.PostAsync().
我设置了HttpContent使用
HttpContent content = new FormUrlEncodedContent(post_parameters); 其中post_parameters是键值对列表List<KeyValuePair<string, string>>
问题是,当HttpContent有一个很大的值(一个图像转换为base64要传输)我得到一个URL太长的错误.这是有道理的 - 因为网址不能超过32,000个字符.但是如何将数据添加到HttpContentif中呢?
请帮忙.
我有一个在IIS7.5服务器上运行的webapi.它有3个控制器,所有3个控制器都可用于从我的应用程序中的调用访问webapi.
我有一个错误,我的控制器的基类将其功能公开,而不是保护.这导致服务器抛出内部服务器错误500(因为抛出了无效的异常"找到了与请求匹配的多个操作").我花了一段时间来深入研究这个,因为它从未触发过我的webapi的日志记录.从这个dicussion 这里,我发现这是发生错误是发生之前的Application_Error功能会赶上它来记录它.所以我将下面的代码添加到我的webapi的global.asax中,现在我可以记录这样的错误.
但是,我现在的问题是,当我在运行我的webapi的本地机器上导致内部服务器错误500与上面完全相同时,我得到了一个日志,我希望看到它的"ExceptionMessage""找到匹配的多个操作"请求"拼写为内部服务器错误的原因.但是当将这个确切的代码部署到服务器并从那里使用webapi时,我的日志只显示"消息":"发生了错误"并且没有向我显示"ExceptionMessage",即使我可以看到异常是使用PerfView抛出.我只需要能够获取我的服务器日志以显示与本地日志显示的信息相同的信息.
public class ResponseExceptionTrapper : DelegatingHandler
{
protected override Task<HttpResponseMessage> SendAsync(
HttpRequestMessage request,
CancellationToken cancellationToken)
{
return base
.SendAsync(request, cancellationToken)
.ContinueWith(response =>
{
var result = response.Result;
if (!result.IsSuccessStatusCode)
{
var exceptionResult = string.Format(
"Response exception: \r\n Path({0}) \r\n Status({1}) \r\n",
request.RequestUri,
result.StatusCode);
if (result.Content != null)
{
var exceptionReadTask =
result.Content.ReadAsStringAsync();
exceptionReadTask.Wait();
exceptionResult += "Message:" +
exceptionReadTask.Result;
}
// Do something appropriate with exceptionResult
exceptionResult.Log();
}
return result;
}, cancellationToken);
}
}
Run Code Online (Sandbox Code Playgroud)
服务器日志示例:
Timestamp: 4/24/2014 …Run Code Online (Sandbox Code Playgroud) 我有一个托管的ASP.NET Web API,可以正常访问http get请求,我现在需要将一些参数传递给PostAsync请求,如下所示:
var param = Newtonsoft.Json.JsonConvert.SerializeObject(new { id=_id, code = _code });
HttpContent contentPost = new StringContent(param, Encoding.UTF8, "application/json");
var response = client.PostAsync(string.Format("api/inventory/getinventorybylocationidandcode"), contentPost).Result;
Run Code Online (Sandbox Code Playgroud)
此调用返回404 Not Found结果.
服务器端API操作如下所示:
[HttpPost]
public List<ItemInLocationModel> GetInventoryByLocationIDAndCode(int id, string code) {
...
}
Run Code Online (Sandbox Code Playgroud)
只是为了确认我在Web API上的路由如下所示:
config.Routes.MapHttpRoute(
name: "DefaultApiWithAction",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
);
Run Code Online (Sandbox Code Playgroud)
我假设我正在错误地传递JSON HttpContent,为什么这将返回状态404?
我正在转变HttpContent为以下dto:
public class ContentDto
{
public string ContentType {get; set;}
public string Headers {get; set; }
public object Data { get; set; }
public ContentDto(HttpContent content)
{
Headers = content.Headers.Flatten();
// rest of the setup
}
}
Run Code Online (Sandbox Code Playgroud)
我正在运行一些单元测试:
[Fact]
public void CanBuild()
{
var content = new StringContent("some json", Enconding.UTF8, "application/json");
var dto = new ContentDto(content);
var contentHeaders = content.Headers.Flatten();
Assert.Equal(contentHeaders, dto.Headers);
}
Run Code Online (Sandbox Code Playgroud)
并且该测试失败,因为Content-Length标题没有被我的dto捕获.但是,如果我这样做:
[Fact]
public void CanBuild()
{
var content = new StringContent("some json", Enconding.UTF8, …Run Code Online (Sandbox Code Playgroud) 我们正在构建一个高度并发的Web应用程序,最近我们已经开始广泛使用异步编程(使用TPL和async/ await).
我们有一个分布式环境,其中应用程序通过REST API(构建在ASP.NET Web API之上)相互通信.在一个特定的应用程序中,我们DelegatingHandler在调用之后base.SendAsync(即,在计算响应之后)将响应记录到文件中.我们在日志中包含响应的基本信息(状态代码,标题和内容):
public static string SerializeResponse(HttpResponseMessage response)
{
var builder = new StringBuilder();
var content = ReadContentAsString(response.Content);
builder.AppendFormat("HTTP/{0} {1:d} {1}", response.Version.ToString(2), response.StatusCode);
builder.AppendLine();
builder.Append(response.Headers);
if (!string.IsNullOrWhiteSpace(content))
{
builder.Append(response.Content.Headers);
builder.AppendLine();
builder.AppendLine(Beautified(content));
}
return builder.ToString();
}
private static string ReadContentAsString(HttpContent content)
{
return content == null ? null : content.ReadAsStringAsync().Result;
}
Run Code Online (Sandbox Code Playgroud)
问题是:当代码达到content.ReadAsStringAsync().Result大量服务器负载时,请求有时会挂起在IIS上.当它发生时,它有时会返回一个响应 - 但它会挂起在IIS上,就像它没有 - 或者在其他时候它永远不会返回.
我也尝试过阅读内容ReadAsByteArrayAsync,然后将其转换为内容String,没有运气.
当我将代码转换为使用异步时,我甚至得到更奇怪的结果:
public static async Task<string> SerializeResponseAsync(HttpResponseMessage response)
{ …Run Code Online (Sandbox Code Playgroud) TL; DR - 如何使用auth标头将JSON字符串发送到REST主机?我尝试了3种不同的方法,其中一种方法适用于匿名类型.为什么我不能使用匿名类型?我需要设置一个名为"Group-Name"的变量,连字符不是有效的C#标识符.
背景
我需要POST JSON但无法获取正文和内容类型
功能#1 - 使用匿名类型
内容类型和数据是正确的,但我不想使用匿名类型.我想用一个字符串
static void PostData(string restURLBase, string RESTUrl, string AuthToken, string postBody)
{
HttpClient client = new HttpClient();
client.BaseAddress = new Uri(restURLBase);
client.DefaultRequestHeaders.Add("Auth-Token", AuthToken);
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
// StringContent content = new StringContent(postBody);
var test1 = "data1";
var test2 = "data2";
var test3 = "data3";
var response = client.PostAsJsonAsync(RESTUrl, new { test1, test2, test3}).Result; // Blocking call!
if (!response.IsSuccessStatusCode)
{
Console.WriteLine("{0} ({1})", (int)response.StatusCode, response.ReasonPhrase);
return;
}
}
Run Code Online (Sandbox Code Playgroud)
输出#1
使用AnonymousTypes + PostAsJsonAsync时,内容类型和数据是正确的,但我不想使用匿名类型.
POST …Run Code Online (Sandbox Code Playgroud) c# ×10
httpcontent ×10
.net ×2
httpclient ×2
asp.net-mvc ×1
async-await ×1
c#-5.0 ×1
http-headers ×1
iis-7.5 ×1
json ×1
rest ×1