C# 使用HttpClient发布自定义类型

C# 使用HttpClient发布自定义类型,c#,asp.net-web-api,dotnet-httpclient,C#,Asp.net Web Api,Dotnet Httpclient,我有一个自定义dto类: public class myObject { public string Id { get; set; } public string Name { get; set; } } 以及使用Web Api(4.5.net framework)的控制器 客户端只有4.0.net framework,因此我无法使用PostAsJsonAsync()方法。将对象从客户端传递到服务器的解决方案是什么 我试过以下方法: var response = Client.

我有一个自定义dto类:

public class myObject
{
    public string Id { get; set; }
    public string Name { get; set; }
}
以及使用Web Api(4.5.net framework)的控制器

客户端只有4.0.net framework,因此我无法使用PostAsJsonAsync()方法。将对象从客户端传递到服务器的解决方案是什么

我试过以下方法:

var response = Client.SendAsync(new HttpRequestMessage<myObject>(objectTest)).Result;

难道不能使用Newtonsoft.Json库吗?

当然可以。只需像这样为自己创建一个新的HttpContent类

  public class JsonContent : HttpContent
    {

        private readonly MemoryStream _Stream = new MemoryStream();

        public JsonContent(object value)
        {

            var jw = new JsonTextWriter(new StreamWriter(_Stream)) {Formatting = Formatting.Indented};
            var serializer = new JsonSerializer();
            serializer.Serialize(jw, value);
            jw.Flush();
            _Stream.Position = 0;

        }
        protected override Task SerializeToStreamAsync(Stream stream, TransportContext context)
        {
            _Stream.CopyTo(stream);
            var tcs = new TaskCompletionSource<object>();
            tcs.SetResult(null);
            return tcs.Task;
        }

        protected override bool TryComputeLength(out long length)
        {
            length = _Stream.Length;
            return true;
        }
    }

创建一个继承自HttpContent的类,该类为您提供网络流,您可以直接向其写入而不使用memoryStream

大概是这样的:

using System;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;

namespace Http.Helper.Extensions
{
    public class JsonHttpContentSerializer : HttpContent
    {

        private object Value { get; set; }

        public JsonHttpContentSerializer(Object value)
        {
            this.Value = value;
        }


        protected override async Task SerializeToStreamAsync(Stream stream, TransportContext context)
        {
            using (var streamWriter = new StreamWriter(stream, new UTF8Encoding(false), 1024, true))
            {
                using (var jsonTextWriter = new JsonTextWriter(streamWriter) { Formatting = Formatting.None })
                {
                    var jsonSerializer = new JsonSerializer();
                    jsonSerializer.Serialize(jsonTextWriter, Value);
                    jsonTextWriter.Flush();
                }
            }

        }

        protected override bool TryComputeLength(out long length)
        {
            length = -1;
            return false;
        }

    }
}
你会喜欢它吗

var jsonSerializeContent = new JsonHttpContentSerializer(someContent);
httpRequestMessage.Content = jsonSerializeContent;

谢谢你的解决方案。我不确定SerializeToStreamAsync做什么,TaskCompletionSource需要结果值的类型。是输入对象还是输出对象?@user1542666很抱歉,我不得不在运行中将if从.net45转换为4.0,并且忘记了
。SerializeToStream方法将在HttpClient需要时将缓冲流复制到网络流。为什么要使用缓冲流?我们可以利用网络流将对象直接写入其中?像这样的<代码>受保护的重写异步任务SerializeToStreamAsync(Stream,TransportContext上下文){StreamWriter=new StreamWriter(Stream,new UTF8Encoding(false));JsonTextWriter=new JsonTextWriter(StreamWriter){Formatting=Formatting.None};JsonSerializer.Serialize(JsonTextWriter,Value);//JsonTextWriter.Flush();}为什么不重写Dispose方法()?@jeevjyotsinghchabda是的,你可以。我通常习惯于使HttpContent类自包含。如果值对象在创建HttpContent对象之后但在写入网络之前发生更改,则有效负载将发生更改。但你的方法是100%有效的。我没有重载dispose,因为这个类没有分配非托管内存。
  var content = new JsonContent(new YourObject());
  var httpClient = new HttpClient();
  var response = httpClient.PostAsync("http://example.org/somewhere", content);
using System;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;

namespace Http.Helper.Extensions
{
    public class JsonHttpContentSerializer : HttpContent
    {

        private object Value { get; set; }

        public JsonHttpContentSerializer(Object value)
        {
            this.Value = value;
        }


        protected override async Task SerializeToStreamAsync(Stream stream, TransportContext context)
        {
            using (var streamWriter = new StreamWriter(stream, new UTF8Encoding(false), 1024, true))
            {
                using (var jsonTextWriter = new JsonTextWriter(streamWriter) { Formatting = Formatting.None })
                {
                    var jsonSerializer = new JsonSerializer();
                    jsonSerializer.Serialize(jsonTextWriter, Value);
                    jsonTextWriter.Flush();
                }
            }

        }

        protected override bool TryComputeLength(out long length)
        {
            length = -1;
            return false;
        }

    }
}
var jsonSerializeContent = new JsonHttpContentSerializer(someContent);
httpRequestMessage.Content = jsonSerializeContent;