2012-03-25 82 views
12

我已经使用MVC4中的新WebAPI功能创建了一个方法,并使其在Azure上运行。该方法要求您发布一个由用户名和密码属性组成的简单LoginModel对象。是的,我打算这确保进一步一旦我得到过去,这速度碰撞:-)方法,然后用JSON格式的对象响应:使用PostAsync,HttpClient和Json从C#Metro UI客户端调用MVC4 WebAPI方法

enter image description here

我可以成功调用使用招此方法,前提是我在请求头中包含“Content-Type:application/json”。它返回一个200,我可以进入提琴手检查并查看JSON响应对象就好了:

enter image description here

不过,我有问题调用使用C#/ XAML在Windows8的一个MetroUI应用此相同的方法。我开始在C#中使用HttpClient和新的Async概念,无论我如何格式化我的Post调用(即使显式调用我希望内容类型为“application/json”),Fiddler都会返回500错误并声明该尝试正在使用Content-Type:“text/html”。我beleive这是问题的根源:

enter image description here

,以发布到这个方法并取回JSON对象我已经尝试了一切可以想到的,这是我最近一次尝试:

HttpClient client = new HttpClient(); 
     client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); 
     HttpContent content = new StringContent(@"{ ""Username"": """ + Username.Text + @", ""Password"": """ + Password.Text + @"""}"); 

     client.PostAsync("http://myapi.com/authentication", content).ContinueWith(result => 
     { 
      var response = result.Result; 

      response.EnsureSuccessStatusCode(); 
     }); 

这导致500错误与内容类型设置为“text/html的”

这里是另一种尝试也失败:

HttpClient httpClient = new HttpClient(); 
HttpResponseMessage response = await httpClient.PostAsync("http://myapi.com/authentication", new StringContent(@"{ ""Username"": """ + Username.Text + @", ""Password"": """ + Password.Text + @"""}", Encoding.UTF8, "application/json")); 
string statusCode = response.StatusCode.ToString(); 

任何人都可以指向正确的方向吗?

刚试过下面的代码由于Nemesv的建议:

HttpClient httpClient = new HttpClient(); 
     HttpContent content = new StringContent(@"{ ""Username"": """ + Username.Text + @", ""Password"": """ + Password.Text + @"""}"); 
     content.Headers.ContentType = new MediaTypeHeaderValue("application/json"); 


     HttpResponseMessage response = await httpClient.PostAsync("http://webapi.com/authentication", content); 

     string statusCode = response.StatusCode.ToString(); 
     response.EnsureSuccessStatusCode(); 

现在显示在我的请求头“应用/ JSON”,但仍显示“text/html的”在Web会话:

enter image description here

回答

22

试试这个设置Headers.ContentType

HttpClient httpClient = new HttpClient(); 
HttpContent content = new StringContent(@"{ ""Username"": """ + "etc." + @"""}"); 
content.Headers.ContentType = new MediaTypeHeaderValue("application/json"); 
HttpResponseMessage response = 
    await httpClient.PostAsync("http://myapi.com/authentication", content); 
string statusCode = response.StatusCode.ToString(); 
+0

谢谢Nemesv。刚刚尝试过,但仍然无法通过500错误,但我注意到在Fiddler中,Header显示它使用“application/json” - 但记录的Web会话显示“text/html”附上一个屏幕抓取。 – CodeAbundance 2012-03-26 00:21:03

+1

仅供参考:查看我原始文章底部的更新。并感谢您的帮助! – CodeAbundance 2012-03-26 00:27:04

+0

供参考:我认为这是我在我的内容标题中设置参数的方式。我在代码中设置了停止位,并在设置了StringContent值后遍历了HttpContent对象,并找不到用户名或密码项。你知道更好的方法发布到WebAPI吗?仍然在我的最后看着它... – CodeAbundance 2012-03-26 00:33:33

6

有一些失踪尝试这是工作。

UserLoginModel user = new UserLoginModel { Login = "username", Password = "password" }; 
string json = Newtonsoft.Json.JsonConvert.SerializeObject(user); 
HttpContent content = new StringContent(json); 
content.Headers.ContentType = new MediaTypeHeaderValue("application/json"); 
HttpClient client = new HttpClient(); 
client.BaseAddress = new Uri("http://localhost:1066/api/"); 
HttpResponseMessage response = client.PostAsync("Authenticate", content).Result; 

if (response.IsSuccessStatusCode) 
{ 
    var result = response.Content.ReadAsAsync<ResultModel>().Result; 
} 
else 
{ 
    return string.Empty; 
} 
+0

这比较好,用JSON.Net序列化对象,而不是手动构建JsonObject字典(这是不必要的代码,只要实体更改就会中断)。 在RTM中,您还可以使用StringContent的构造函数来指定媒体类型和编码,例如以UTF8为例。 var content = new StringContent(json,Encoding.UTF8,“application/json”)。 – 2013-01-29 14:36:29

+1

是的,谢谢它为我工作.. – andy 2013-03-08 07:20:27