小编典典

将WCF 4中的默认JSON序列化器替换为JSON.NET

json

我想用JSON.NET替换默认的WCF JSON(对于所有数据类型)序列化。我在网上搜索了所有内容,却找不到有效的解决方案。

这是我的对象:

        [JsonObject]
    public class TestObject
    {
        [JsonProperty("JsonNetName")]
        public string Name = "John";

        [JsonProperty]
        public DateTime Date = DateTime.Now;
    }

这是我的WCF函数:

        [OperationContract]
        [WebGet(BodyStyle = WebMessageBodyStyle.Bare, ResponseFormat = WebMessageFormat.Json)]
        List<TestObject> Get();

这是Global.asax中的代码:

            protected void Application_Start(object sender, EventArgs e)
        {
            // Create Json.Net formatter serializing DateTime using the ISO 8601 format
            var serializerSettings = new JsonSerializerSettings();

            serializerSettings.Converters.Add(new IsoDateTimeConverter());
            serializerSettings.Converters.Add(new BinaryConverter());
            serializerSettings.Converters.Add(new JavaScriptDateTimeConverter());
            serializerSettings.Converters.Add(new BinaryConverter());
            serializerSettings.Converters.Add(new StringEnumConverter());

            var config = HttpHostConfiguration.Create().Configuration;

            Microsoft.ApplicationServer.Http.JsonMediaTypeFormatter jsonFormatter = config.OperationHandlerFactory.Formatters.JsonFormatter;

            config.OperationHandlerFactory.Formatters.Remove(jsonFormatter);

            config.OperationHandlerFactory.Formatters.Insert(0, new JsonNetMediaTypeFormatter(serializerSettings));

            var httpServiceFactory = new HttpServiceHostFactory
            {
                OperationHandlerFactory = config.OperationHandlerFactory,
                MessageHandlerFactory = config.MessageHandlerFactory
            };

            //Routing
            RouteTable.Routes.Add(
               new ServiceRoute(
                   "Brands", httpServiceFactory,
                   typeof(Brands)));

          }

这是Web.Config:

     <endpointBehaviors>
        <behavior name="Behavior_Brands">
          <webHttp defaultOutgoingResponseFormat="Json" defaultBodyStyle="Bare" />
        </behavior>
      </endpointBehaviors>

和服务部分:

    <service name="TestApp.CoreWCF.Brands">
        <endpoint address="" behaviorConfiguration="Behavior_Brands" binding="webHttpBinding" contract="TestApp.CoreWCF.IBrands">
          <identity>
            <dns value="localhost" />
          </identity>
        </endpoint>
      </service>

最后,这是启动URL时得到的:

http:// localhost:30000 / Brands / Get

[{"Date":"\/Date(1354364412708+0200)\/","Name":"John"}, {"Date":"\/Date(1354364412708+0200)\/","Name":"John"}]

JSON答案显然会忽略JSON.NET属性。


阅读 352

收藏
2020-07-27

共1个答案

小编典典

无论如何,我想出了一种手动使用其他序列化器的方法,它似乎更高效,更快捷,因为它不会通过Microsoft的序列化器,尽管从代码角度来看,它有点麻烦。

  1. 在接口和实现它们的类中,将所有返回类型设置为“ System.ServiceModel.Channels.Message”。
        [OperationContract]
    [WebGet(BodyStyle = WebMessageBodyStyle.Bare, ResponseFormat = WebMessageFormat.Json)]
    System.ServiceModel.Channels.Message GetData(); 
  1. 创建一个扩展方法,以便您可以使用JSON.NET序列化器(或您要使用的任何一种)轻松地从对象中构建内存流。
        public static System.ServiceModel.Channels.Message GetJsonStream(this object obj)
    {
        //Serialize JSON.NET
        string jsonSerialized = JsonConvert.SerializeObject(obj);

        //Create memory stream
        MemoryStream memoryStream = new MemoryStream(new UTF8Encoding().GetBytes(jsonSerialized));

        //Set position to 0
        memoryStream.Position = 0;

        //return Message
        return WebOperationContext.Current.CreateStreamResponse(memoryStream, "application/json");
    }
  1. 在方法的主体中,将直接序列化的对象返回到流中
    return yourObject.GetJsonStream();
    
2020-07-27