0

I know there are several posts over the years on this: Sorry they wont let me add this many links ??

to link a few..but none of these are complete and citing the full scope of technologies needed...typically referencing a class that is ellusive to find...With that I will post what I have and the bottom line is while the formatter DO get into the formatters collection the custom formatter is not called. Now it could be that I am using the complete wrong solution but no solution seems clear...and this should be easy to accomplish. I have tried every content-type possible as well as the following:

Model:

        public class TEST_Hotel : IHotelOption
{

    public int AlternateCount{get;set;}                            
    public float AverageBaseRate{get;set;}       
    public List<string> policyViolations{get;set;}                 
    public int TravelerBookings{get;set;}                       
     [JsonProperty("hotelId")]
    public string VendorHotelID{get;set;}     

}

Adding the [DataContract] [DataMember] attributes of course will work as it will use the DataContract serializer and NOT the custom serializer. Note: that the JsonProperty is NOT recognized since the custom json.net formatter is not used.

Service:

 [OperationContract]
    [Description("Retrieves a list of hotel objects based on search parameters")]
    [WebGet(
         BodyStyle = WebMessageBodyStyle.WrappedRequest,
  //      ResponseFormat = WebMessageFormat.Json,
   //     RequestFormat = WebMessageFormat.Json,
        UriTemplate = "GetHotels?queryparams={parameters}")]
    public HotelResults GetHotels(string parameters)
    {
        return worker.GetHotels(parameters);
    }

Global:

          using System;
         using System.ServiceModel.Activation;
         using System.Web.Routing;
         using System.Web;
         using System.Linq;
        using System.Web.Http;

    namespace HotelService
    {
    public class Global : System.Web.HttpApplication
    {
    private void Application_Start(object sender, EventArgs e)
    {

        RegisterRoutes();
    }


    private void RegisterRoutes()
    {
        RouteTable.Routes.Add(new ServiceRoute("", new WebServiceHostFactory(), typeof(Hotels)));
        GlobalConfiguration.Configuration.Formatters.Insert(0, new JsonNetMediaTypeFormatter() );
    }


}

    }

JsonNetMediaTypeFormatter:

     using Newtonsoft.Json;
     using System;
     using System.Collections.Generic;
     using System.Collections.ObjectModel;
     using System.IO;
     using System.Linq;
     using System.Net;
     using System.Net.Http;
     using System.Net.Http.Formatting;
     using System.Net.Http.Headers;
     using System.Threading.Tasks;
     using System.Web;

     namespace HotelService
     {

    public sealed class JsonNetMediaTypeFormatter : JsonMediaTypeFormatter
    {
        public JsonSerializer Serializer
        {
            get;
            private set;
        }

        public JsonNetMediaTypeFormatter(JsonSerializer serializer = null)
        {

            Collection<MediaTypeHeaderValue> supportedMediaTypes = base.SupportedMediaTypes;
            MediaTypeHeaderValue mediaTypeHeaderValue = new MediaTypeHeaderValue("application/json");
            mediaTypeHeaderValue.CharSet = "UTF-8";
            supportedMediaTypes.Add(mediaTypeHeaderValue);
            Collection<MediaTypeHeaderValue> mediaTypeHeaderValues = base.SupportedMediaTypes;
            MediaTypeHeaderValue mediaTypeHeaderValue1 = new MediaTypeHeaderValue("text/json");
            mediaTypeHeaderValue1.CharSet = "UTF-8";
            mediaTypeHeaderValues.Add(mediaTypeHeaderValue1);
            this.Serializer = (serializer != null ? serializer : new JsonSerializer());


        }

        public override Task<object> ReadFromStreamAsync(Type type, Stream readStream, HttpContent content, IFormatterLogger formatterLogger)
        {
            return readStream.ReadAsJson(type, this.Serializer);
        }

        public override Task WriteToStreamAsync(Type type, object value, Stream writeStream, HttpContent content, TransportContext transportContext)
        {
            return writeStream.WriteAsJson(value, this.Serializer);
        }

        public override bool CanReadType(Type type)
        {
            return false;
        }

        public override bool CanWriteType(Type type)
        {
            return true;
        }



    }

    internal static class StreamExtensions
    {
        internal static Task<object> ReadAsJson(this Stream stream, Type instanceType, JsonSerializer serializer)
        {
            if (stream == null)
            {
                return null;
            }
            return Task<object>.Factory.StartNew(() =>
            {
                object obj1;
                using (JsonTextReader reader = new JsonTextReader(new StreamReader(stream)))
                {
                    object obj = serializer.Deserialize(reader);
                    obj1 = (obj.GetType().IsSubclassOf(instanceType) ? obj : serializer.Deserialize(reader, instanceType));
                }
                return obj1;
            });
        }

        internal static Task WriteAsJson(this Stream stream, object instance, JsonSerializer serializer)
        {
            if (instance == null)
            {
                return null;
            }
            return Task.Factory.StartNew(() =>
            {
                using (JsonTextWriter writer = new JsonTextWriter(new StreamWriter(stream)))
                {
                    serializer.Serialize(writer, instance);
                    writer.Flush();
                }
            });
        }
        }

       }

packages:

    <packages>
      <package id="Microsoft.AspNet.WebApi" version="5.2.3" targetFramework="net451" />
       <package id="Microsoft.AspNet.WebApi.Client" version="5.2.3" targetFramework="net451" />
       <package id="Microsoft.AspNet.WebApi.Core" version="5.2.3" targetFramework="net451" />
       <package id="Microsoft.AspNet.WebApi.WebHost" version="5.2.3" targetFramework="net451" />
        <package id="Newtonsoft.Json" version="8.0.3" targetFramework="net451" />
      </packages>

What happens is if I remove the Service ResponseFormat then xml is returned if i put it back json is returned but the custom formatter is not used. Breaking in global i can see the custom formatter at the 0 index of the collection.It would appear a mapper or some binding is missing.

DDaniel
  • 1
  • 1
  • Did you also check this answer? https://stackoverflow.com/questions/9827933/json-net-serializer-for-wcf-rest-services – dbc Jun 02 '16 at 19:34
  • Yes I have seen similar code ( I have lots of commented code examples) the issue is in the line " var config = HttpHostConfiguration.Create().Configuration;" where (in 2016) can one find the class HttpHostConfiguration ? or var httpServiceFactory = new HttpServiceHostFactory ? current code for the route table looks like: RouteTable.Routes.Add(new ServiceRoute("", new WebServiceHostFactory(), typeof(Hotels))); taking a WebServiceHostFactory....no reference found anywhere in the reference assemblies for HttpServiceHostFactory – DDaniel Jun 03 '16 at 17:35

0 Answers0