user1542666
user1542666

Reputation: 170

Posting a Custom type with HttpClient

I have a custom dto class:

public class myObject
{
    public string Id { get; set; }
    public string Name { get; set; }
}

and a Controller using Web Api (4.5 .net framework)

[HttpPost]
public IHttpActionResult StripArchiveMailboxPermissions(myObject param)
{
    DoSomething(param);
    return OK();
}

The client side only has 4.0 .net framework So I won't be able to use the PostAsJsonAsync() method. what is the solution to pass the object from my client to the server?

I have tried somethinig like the following:

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

however it throws me the exception:

Could not load file or assembly 'Microsoft.Json, Version=2.0.0.0, 
Culture=neutral, PublicKeyToken=31bf3856ad364e35' or one of its dependencies. 
The system cannot find the file specified.

Isn't it possible to use the Newtonsoft.Json library?

Upvotes: 2

Views: 10600

Answers (2)

jeevjyot singh chhabda
jeevjyot singh chhabda

Reputation: 637

Create a class inheriting from HttpContent, which gives you the network stream and you can write directly to it and not use the memoryStream

Something like this:

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

    }
}

and you would use like it

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

Upvotes: 1

Darrel Miller
Darrel Miller

Reputation: 142044

Sure. Just create yourself a new HttpContent class like this...

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

and now you can send your object as Json just like this

  var content = new JsonContent(new YourObject());
  var httpClient = new HttpClient();
  var response = httpClient.PostAsync("http://example.org/somewhere", content);

Upvotes: 9

Related Questions