如何正确使用HttpClient PostAsync的参数?

12

所以我正在使用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页面未找到。我应该如何正确使用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);
        }
3个回答

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

使用异步版本,我该如何获取返回的字符串? - Aleks Slade
@AleksSlade 取决于请求的上下文环境。请遵循异步调用的规则。var result = await HttpClientExtension.PostRequestAsync("此处URL", "此处参数") - Nkosi

4

您需要准备对象,然后使用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);

2

我已经使用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();
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接