【问题标题】:How do I use HttpClient PostAsync parameters properly?如何正确使用 HttpClient PostAsync 参数?
【发布时间】:2017-12-22 16:13:30
【问题描述】:

所以我正在使用 HttpClient 为我的项目编写一个扩展类,因为我要从 HttpWebRequest 迁移过来。

在进行 POST 请求时,如何发送一个普通字符串作为参数?没有 json 或任何东西,只是一个简单的字符串。

这就是目前的样子。

static class HttpClientExtension
    {
        static HttpClient client = new HttpClient();
        public static string GetHttpResponse(string URL)
        {
            string fail = "Fail";
            client.BaseAddress = new Uri(URL);
            HttpResponseMessage Response = client.GetAsync(URL).GetAwaiter().GetResult();
            if (Response.IsSuccessStatusCode)
                return Response.Content.ReadAsStringAsync().GetAwaiter().GetResult();
            else
                return fail;
        }

        public static string PostRequest(string URI, string PostParams)
        {
            client.PostAsync(URI, new StringContent(PostParams));
            HttpResponseMessage response = client.GetAsync(URI).GetAwaiter().GetResult();
            string content = response.Content.ReadAsStringAsync().GetAwaiter().GetResult();
            return content;
        }
    }

如果你这样看

client.PostAsync(URI, new StringContent(PostParams));

您可以看到我刚刚尝试创建新的 StringContent 并将字符串传递给它,响应返回 404 page not found。 如何正确使用 Post.Async();发送字符串或字节数组?因为使用 HttpWebRequest 你会这样做

public static void SetPost(this HttpWebRequest request, string postdata)
        {
            request.Method = "POST";
            byte[] bytes = Encoding.UTF8.GetBytes(postdata);

            using (Stream requestStream = request.GetRequestStream())
                requestStream.Write(bytes, 0, bytes.Length);
        }

【问题讨论】:

    标签: c# .net httpwebrequest httpclient httpwebresponse


    【解决方案1】:

    PostRequest 中完成了以下操作..

    client.PostAsync(URI, new StringContent(PostParams));
    HttpResponseMessage response = client.GetAsync(URI).GetAwaiter().GetResult();
    

    不捕获 POST 的响应。

    重构为

    public static string PostRequest(string URI, string PostParams) {            
        var response = client.PostAsync(URI, new StringContent(PostParams)).GetAwaiter().GetResult();
        var content = response.Content.ReadAsStringAsync().GetAwaiter().GetResult();
        return content;
    }
    

    HttpClient 主要用于异步,因此请考虑重构为

    public static async Task<string> PostRequestAsync(string URI, string PostParams) {            
        var response = await client.PostAsync(URI, new StringContent(PostParams));
        var content = await response.Content.ReadAsStringAsync();
        return content;
    }
    

    【讨论】:

    • 使用异步版本如何获取返回字符串?
    • @AleksSlade 取决于发出请求的上下文。应用有关如何进行异步调用的规则。 var result = await HttpClientExtension.PostRequestAsync("URL here", "Params Here")
    【解决方案2】:

    您需要准备对象,然后您将使用Newtonsoft.Json 序列化对象。之后,您将从缓冲区准备字节内容。我们正在使用 api url api/auth/login 并且它不是完整的 api url,因为我们使用了依赖注入并在启动时配置了基地址,请参见第二个代码。

    public async void Login(string username, string password)
        {
            LoginDTO login = new LoginDTO();
            login.Email = username;
            login.Password = password;
            var myContent = JsonConvert.SerializeObject(login);
            var buffer = System.Text.Encoding.UTF8.GetBytes(myContent);
            var byteContent = new ByteArrayContent(buffer);
            byteContent.Headers.ContentType = new MediaTypeHeaderValue("application/json");
    
            var response = await httpClient.PostAsync("api/auth/login", byteContent);
            var contents = await response.Content.ReadAsStringAsync();
        }
    
    services.AddHttpClient<IAuthService, AuthService>(client =>
            {
                client.BaseAddress = new Uri("https://localhost:44354/");
            });
    

    .NET 5 解决方案

    在 .NET 5 中,有一个新类 JsonContent,您可以轻松实现它

    LoginDTO login = new LoginDTO();
    login.Email = username;
    login.Password = password;
    
    JsonContent content = JsonContent.Create(login);
    var url = "http://...";
    HttpResponseMessage response = await httpClient.PostAsync(url, content);
    

    【讨论】:

      【解决方案3】:

      我已经完成了以下工作(使用包 Ngonzalez.ImageProcessorCore)。

      查询(ASP.NET Core 2 控制器):

      async Task<byte[]> CreateImage(IFormFile file)
      {
        using (var memoryStream = new MemoryStream())
        {
          await file.CopyToAsync(memoryStream);
          var image = new Image(memoryStream);
          var height = image.Height < 150 ? image.Height : 150;
          image.Resize((int)(image.Width * height / image.Height), height).Save(memoryStream);
          return memoryStream.ToArray();
        }
      }
      
      [HttpPost, ValidateAntiForgeryToken]
      public async Task<IActionResult> ImageAdd(ImageAddVm vm)
      {
        byte[] image = null;
        if (vm.File != null && vm.File.Length > 0)
           image = await CreateImage(vm.File);
        if (image != null)
        {
          var json = JsonConvert.SerializeObject(new { vm.ObjectId, image });
          var content = new StringContent(json, Encoding.UTF8, "application/json");
          var client= new HttpClient();
          await client.PostAsync($"{ApiUrl}/SaveImage", content);
        }
        return RedirectToAction("ReturnAction");
      }
      

      API(ASP.NET Core 2 控制器):

      public class ObjectImage
      {
        public int ObjectId { get; set; }
        public byte[] Image { get; set; }
      }
      
      [HttpPost("SaveImage")]
      public void SaveImage([FromBody]object content)
      {
        var obj = JsonConvert.DeserializeObject<ObjectImage>(content.ToString());
        _db.Images.Find(obj.ObjectId).Image = obj.Image;
        _db.SaveChanges();
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多