【问题标题】:Calling MVC4 WebAPI methods from C# Metro UI Client using PostAsync, HttpClient & Json使用 PostAsync、HttpClient 和 Json 从 C# Metro UI Client 调用 MVC4 WebAPI 方法
【发布时间】:2012-03-25 19:10:26
【问题描述】:

我使用 MVC4 中的新 WebAPI 功能创建了一个方法,并让它在 Azure 上运行。该方法要求您发布一个简单的 LoginModel 对象,该对象由 Username 和 Password 属性组成。是的,一旦我克服了这个减速带,我计划进一步保护它:-) 然后该方法以 Json 格式的对象响应:

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

但是,我在使用 C#/XAML 从 Windows8 中的 MetroUI 应用程序调用相同方法时遇到问题。我开始在 C# 中使用 HttpClient 和新的 Async 概念,无论我如何格式化我的 Post 调用(即使明确指出我希望 Content-Type 为“application/json”)Fiddler 返回一个 500 错误并声明尝试使用 Content-Type:"text/html"。我相信这是问题的根源:

为了发布到这个方法并取回 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();
        });

这会导致 Content-Type 设置为“text/html”时出现 500 错误

这是另一个失败的尝试:

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();

它现在在我的请求标头中显示“application/json”,但在 Web 会话中仍然显示“text/html”:

【问题讨论】:

    标签: c# httpclient windows-8 microsoft-metro asp.net-mvc-4


    【解决方案1】:

    试试这个设置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();
    

    【讨论】:

    • 感谢 Nemesv。刚刚尝试过,但仍然无法通过 500 错误,但我注意到在 Fiddler 中,标题显示它正在使用“application/json” - 但是记录的网络会话显示“text/html”我会附上屏幕截图。
    • 仅供参考:请参阅我原始帖子底部的更新。并感谢您的帮助!
    • 仅供参考:我认为这是我在内容标题中设置参数的方式。在设置 StringContent 值后,我停止了代码并遍历了 HttpContent 对象,但找不到用户名或密码项。您知道将其发布到 WebAPI 的更好方法吗?我还在调查它...
    • 我做了一些测试,它工作正常。但是我发现如果 Json 有问题,它就会失败。例如,您在这里错过了"Username.Text + @""", ""Password"": """。无论如何,您应该使用 Json.net 之类的 Json serilazer,而不是手动操作。
    • 感谢 Nemesv!今晚晚些时候我会落实你的建议并通知你!
    【解决方案2】:

    有一些遗漏尝试这是有效的。

    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;
    }
    

    【讨论】:

    • 这样更好,使用 JSON.Net 序列化对象,而不是手动构建 JsonObject 字典(这是不必要的代码,一旦实体更改就会中断)。在 RTM 中也可以使用 StringContent 的构造函数来指定媒体类型和编码,以 UTF8 为例,e.g. var content = new StringContent(json, Encoding.UTF8, "application/json").
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-02
    • 2018-04-11
    相关资源
    最近更新 更多