Using Serializable attribute on Model in WebAPI

夙愿已清 提交于 2019-11-26 21:32:20

问题


I have the following scenario: I am using WebAPI and returning JSON results to the consumer based on a model. I now have the additional requirement to serialize the models to base64 to be able to persist them in cache and/or use them for auditing purposes. Problem is that when I add the [Serializable] attribute to the model so for converting the the model to Base64, the JSON output changes as follows:

The Model:

[Serializable]
public class ResortModel
{
    public int ResortKey { get; set; }

    public string ResortName { get; set; }
}

Without the [Serializable] attribute the JSON output is:

{
    "ResortKey": 1,
    "ResortName": "Resort A"
}

With the [Serializable] attribute the JSON output is:

{
    "<ResortKey>k__BackingField": 1,
    "<ResortName>k__BackingField": "Resort A"
}

How would I be able to use the [Serializable] attribute without changing the output of the JSON?


回答1:


By default, Json.NET ignores the Serializable attribute. However, according to a comment to this answer by Maggie Ying (quoted below because comments are not meant to last), WebAPI overrides that behavior, which causes your output.

Json.NET serializer by default set the IgnoreSerializableAttribute to true. In WebAPI, we set that to false. The reason why you hit this issue is because Json.NET ignores properties: "Json.NET now detects types that have the SerializableAttribute and serializes all the fields on that type, both public and private, and ignores the properties" (quoted from james.newtonking.com/archive/2012/04/11/…)

A simple example that demonstrates the same behavior without WebAPI can look like this:

using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using System;
namespace Scratch
{
    [Serializable]
    class Foo
    {
        public string Bar { get; set; }
    }

    class Program
    {
        static void Main()
        {
            var foo = new Foo() { Bar = "Blah" };
            Console.WriteLine(JsonConvert.SerializeObject(foo, new JsonSerializerSettings()
                {
                    ContractResolver = new DefaultContractResolver()
                    {
                        IgnoreSerializableAttribute = false
                    }
                }));
        }
    }
}

There are several ways around this behavior. One is to decorate your model with a plain JsonObject attribute:

[Serializable]
[JsonObject]
class Foo
{
    public string Bar { get; set; }
}

Another way is to override the default settings in your Application_Start(). According to this answer, the default settings should do it:

GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings = new Newtonsoft.Json.JsonSerializerSettings();

If that doesn't work, you could be explicit about it:

GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings = new JsonSerializerSettings()
    {
        ContractResolver = new DefaultContractResolver()
        {
            IgnoreSerializableAttribute = true
        }
    };


来源:https://stackoverflow.com/questions/29962044/using-serializable-attribute-on-model-in-webapi

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!