【问题标题】:HttpClient form submission with json return带有json返回的HttpClient表单提交
【发布时间】:2020-09-15 03:17:23
【问题描述】:

提前致谢。

我们正在开发 oAuth2 流程,需要一些帮助。给出的要求是使用嵌入的表单变量 POST 到服务器,并期望服务器以 JSON 格式响应。该文档有一个类似的序列,涉及一个返回 JSON 的 GET 请求,并且一个非常相似的方法可以很好地获取响应。但是,在这种情况下,它会给出一个对象引用错误,说明响应为空。我们从服务器收到一条内容长度为 1929 的 200 OK 消息,它说内容类型是 application/json,所以我完全有理由相信内容存在于某处。

public rsAccessToken Signup(string Code, string State, string redirect_uri)
        {

            HttpClient client = new HttpClient();
            rsAccessToken rt = null;
            HttpResponseMessage response = null;
            client.BaseAddress = new Uri(URLtoken);
            string grant_type = "authorization_code";

            client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/x-www-form-urlencoded"));
            var byteArray = Encoding.ASCII.GetBytes(string.Format("{0}:{1}", clientid, secret));
            client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", Convert.ToBase64String(byteArray));
            HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, URLtoken);
            var parameters = new Dictionary<string, string> { { "grant_type", grant_type }, { "code", Code }, { "state", State }, { "redirect_uri", redirect_uri } };
            var encodedContent = new FormUrlEncodedContent(parameters);
            Task task = client.PostAsync(URLtoken, encodedContent)
           .ContinueWith((taskwithresponse) =>
           {
               Task<string> jsonString = response.Content.ReadAsStringAsync();
               jsonString.Wait();
               rt = JsonConvert.DeserializeObject<rsAccessToken>(jsonString.Result);
           });
            task.Wait();

            client.Dispose();

            return rt;
        }

在 taskwithresponse 点捕获的响应是:

Id = 104, Status = RanToCompletion, Method = "{null}", Result = "StatusCode: 200, ReasonPhrase: 'OK', Version: 1.1, Content: System.Net.Http.StreamContent, Headers:\r\n{\r\n  Connection: keep-alive\r\n  Date: Mon, 14 Sep 2020 14:41:55 GMT\r\n  ETag: W/\"789-W2Me6TSLLmO4+fEmAtfH4YWXhxs\"\r\n  Set-Cookie: TS0108eb76=0119a2687f0aa2133862c3de61eb2485030f83265a0e1bcb62403e1c777052fccfeacf2df6a14e78b161afc6a43cfc2622532765bc; Max-Age=900; Path=/\r\n  Content-Length: 1929\r\n  Content-Type: application/json; charset=utf-8\r\n}"

感谢您的帮助。

【问题讨论】:

  • response 是如何填充的?你打算使用taskwithresponse吗?
  • 在获取请求中,使用了以下代码并且响应填充良好。任务 task = client.SendAsync(request) .ContinueWith((taskwithresponse) => { Task jsonString = response.Content.ReadAsStringAsync(); jsonString.Wait(); rs = JsonConvert.DeserializeObject (jsonString.Result); });
  • 我不确定响应是如何填充的……我从网上的一个示例中获取了 lambda 表达式,当它起作用时……从兔子洞里跑了下来,再也没有回头。我可以在这方面使用教育。我并不像我希望的那样精通新的任务模型。
  • 就是这样。谢谢您的答复。更改为 taskwithresponse.Result.Content.ReadAsStringAsync();解决它。对我来说,以前如何填充响应是不合逻辑的,但它是在 get 中,所以我没有想太多。非常感谢您的快速反应
  • 您可以将Signup 转换为aysnc 类型吗?如果是,那么您在异步操作中使用等待,您可以在其中检查输出。转换为纯异步链后,我已经发布了答案。 @Greg - 请检查

标签: c# oauth-2.0 dotnet-httpclient


【解决方案1】:

正确的代码是:

public rsAccessToken VeteranSignup(string Code, string State, string redirect_uri)
    {

        HttpClient client = new HttpClient();
        rsAccessToken rt = null;
        client.BaseAddress = new Uri(URLtoken);
        string grant_type = "authorization_code";

        client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/x-www-form-urlencoded"));
        var byteArray = Encoding.ASCII.GetBytes(string.Format("{0}:{1}", clientid, secret));
        client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", Convert.ToBase64String(byteArray));
        HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, URLtoken);
        var parameters = new Dictionary<string, string> { { "grant_type", grant_type }, { "code", Code }, { "state", State }, { "redirect_uri", redirect_uri } };
        var encodedContent = new FormUrlEncodedContent(parameters);
        Task task = client.PostAsync(URLtoken, encodedContent)
       .ContinueWith((taskwithresponse) =>
       {
           Task<string> jsonString = taskwithresponse.Result.Content.ReadAsStringAsync();
           jsonString.Wait();
           rt = JsonConvert.DeserializeObject<rsAccessToken>(jsonString.Result);
       });
        task.Wait();

        client.Dispose();

        return rt;
    }

【讨论】:

    【解决方案2】:
    1. 你应该使用taskwithreponse

    2. 此外,您应该使用纯 aysnc 链。不要通过 aynsc 调用来同步调用。

       public async Task<rsAccessToken> Signup(string Code, string State, string redirect_uri)
       {
           using(HttpClient client = new HttpClient())
           {
              rsAccessToken rt = null;
      
              client.BaseAddress = new Uri(URLtoken);
              string grant_type = "authorization_code";
      
              client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/x-www-form-urlencoded"));
              var byteArray = Encoding.ASCII.GetBytes(string.Format("{0}:{1}", clientid, secret));
              client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", Convert.ToBase64String(byteArray));
              var(HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, URLtoken))
              {
                    var parameters = new Dictionary<string, string> { { "grant_type", grant_type }, { "code", Code }, { "state", State }, { "redirect_uri", redirect_uri } };
                    var encodedContent = new FormUrlEncodedContent(parameters);
                    HttpResponseMessage response = await client.PostAsync(URLtoken, encodedContent)
      
                   var jsonString = await response.Content.ReadAsStringAsync();
                   rt = JsonConvert.DeserializeObject<rsAccessToken>(jsonString.Result);
              }
      
           return rt;
         }
       }
      

    【讨论】:

    • 我正在根据您的帖子进行修改。请稍等,我在您提供的示例中有一些错误需要解决
    • @Greg - 如果您需要任何其他详细信息,请告诉我
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多