【问题标题】:HttpClient post returns bad request in c#, works in postmanHttpClient post在c#中返回错误请求,在邮递员中工作
【发布时间】:2019-06-07 20:47:16
【问题描述】:

我正在尝试访问休息端点https://api.planet.com/auth/v1/experimental/public/users/authenticate。它在请求正文中期望 json。

我可以得到在 Postman 中工作的请求,但不能使用 c#。使用邮递员我会收到预期的无效电子邮件或密码消息,但无论我尝试如何使用我的代码,我都会收到“错误请求”。

这是发出请求的代码

private void Login()
{
    try
    {
        HttpClient client = new HttpClient();
        client.BaseAddress = new Uri("https://api.planet.com/");
        client.DefaultRequestHeaders.Accept.Clear();
        //ClientDefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
        client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("*/*"));
        Data.User user = new Data.User
        {
            email = "myemail@company.com",
            password = "sdosadf"
        };
        var requestMessage = JsonConvert.SerializeObject(user);
        var content = new StringContent(requestMessage, Encoding.UTF8, "application/json");
        var response = client.PostAsync("auth/v1/experimental/public/users/authenticate", content).Result;
        Console.WriteLine(response.ToString());
    }
    catch (WebException wex )
    {
        MessageBox.Show(wex.Message) ;
    }
}
class User
{
    public string email;
    public string password;
}

这里是 Postman 正在工作的屏幕截图

【问题讨论】:

  • 您是否尝试过为MediaTypeWithQualityHeaderValue 使用合适的值?
  • 你在设置代理吗?
  • @DavidG 是的,我已经尝试设置 //ClientDefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));但没有运气
  • @SenadMeškin 不,我没有考虑过,我现在就试试。

标签: c# rest dotnet-httpclient


【解决方案1】:

实现此功能的方法是更改​​内容标题“内容类型”。默认情况下,HTTPClient 正在创建 content-type: application/json;characterset= UTF8。我删除并重新创建了没有字符集部分的内容标题,并且它起作用了。

content.Headers.Remove("Content-Type");
content.Headers.Add("Content-Type", "application/json");

【讨论】:

  • 非常感谢,@Dowlers。昨天我花了半天时间思考可能出了什么问题。
【解决方案2】:

问题是您尝试调用async 方法而不等待使用await methodvar task = method; task.Wait() 的响应因此,当您最终执行response.ToString() 时,它会返回您看到的文本。

在非异步方法中处理此问题的一种方法是执行以下操作:

var task = client.PostAsync("auth/v1/experimental/public/users/authenticate", content);
task.Wait();
var responseTask = task.Content.ReadAsStringAsync();
responseTask.Wait();
Console.WriteLine(responseTask.Result);

另一种方法是通过执行private async void Login() 使当前方法异步,然后执行:

var postResp = await client.PostAsync("auth/v1/experimental/public/users/authenticate", content);
var response = await postResp.Content.ReadAsStringAsync();
Console.WriteLine(response);

【讨论】:

  • 我尝试了你的两个建议,但都没有奏效。但是,它们确实会稍微更改错误消息。当我等待 task.Content.ReadAsStringAsync() 消息更改为“需要应用程序/json”
  • 感谢您的建议使我找到了最终的解决方案。当正确读取结果时,新的错误消息帮助我弄清楚其余端点没有正确解析我的标头。我不得不删除并重新创建内容类型标题,然后它就可以工作了。
【解决方案3】:

创建这样的方法...

    static async Task<string> PostURI(Uri u, HttpContent c)
    {            

        var response = string.Empty;
        var msg = "";
        using (var client = new HttpClient())
        {
            HttpResponseMessage result = await client.PostAsync(u, c);
             msg = await result.Content.ReadAsStringAsync();              
            if (result.IsSuccessStatusCode)
            {                   
                response = result.StatusCode.ToString();                    

            }
        } 
        return response;
    }

调用你的方法

public void Login()
    {
        string postData ="{\"email\":\"your_email\",\"password\":\"your_password\"}";
        Uri u = new Uri("yoururl");
        var payload = postData;

        HttpContent c = new StringContent(payload, Encoding.UTF8,"application/json");
        var t = Task.Run(() => PostURI(u, c));
        t.Wait();
        Response.Write(t.Result);
    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-21
    • 1970-01-01
    • 2021-08-31
    • 1970-01-01
    相关资源
    最近更新 更多