Как добавить пользовательский корневой узел при сериализации объекта с помощью JSON.NET?

я добавил пользовательское свойство к некоторым из моих объектов, как это:

[JsonCustomRoot("status")]
public class StatusDTO 
{
    public int StatusId { get; set; }
    public string Name { get; set; }
    public DateTime Created { get; set; }
}

атрибут очень просто:

public class JsonCustomRoot :Attribute
{
    public string rootName { get; set; }

    public JsonCustomRoot(string rootName)
    {
        this.rootName = rootName;
    }
}

вывод по умолчанию из JSON.NET при сериализации экземпляра объекта происходит следующее:

{"StatusId":70,"Name":"Closed","Created":"2012-12-12T11:50:56.6207193Z"}

теперь вопрос: как я могу добавить корневой узел в JSON со значением пользовательского атрибута, например:

{status:{"StatusId":70,"Name":"Closed","Created":"2012-12-12T11:50:56.6207193Z"}}

я нашел несколько статей с упоминанием IContractResolver интерфейс, но я не могу понять как это сделать. Мои попытки включают этот незавершенный фрагмент кода:

protected override JsonObjectContract CreateObjectContract(Type objectType)
{
    JsonObjectContract contract = base.CreateObjectContract(objectType);

    var info = objectType.GetCustomAttributes()
                   .SingleOrDefault(t => (Type)t.TypeId==typeof(JsonCustomRoot));
    if (info != null)
    {
        var myAttribute = (JsonCustomRoot)info;
        // How can i add myAttribute.rootName to the root from here?
        // Maybe some other method should be overrided instead?
    }

    return contract;
}

4 ответов


вот решение специально для веб-API, которое я также использую:RootFormatter.cs

Я написал его на основе создание Форматера JSONP для ASP.NET Web API.

вместо использования пользовательского атрибута я повторно использую поле заголовка JsonObjectAttribute. Вот код использования:

using Newtonsoft.Json

[JsonObject(Title = "user")]
public class User
{
    public string mail { get; set; }
}

затем добавьте RootFormatter в свой App_Start и зарегистрируйте его следующим образом в WebApiConfig:

GlobalConfiguration.Configuration.Formatters.Insert(0, new RootFormatter());

я смог получить завернутый ответ подобный :

{"user":{
  "mail": "foo@example.com"
}}

что если вы используете анонимный объект?

JSON.Serialize(new { status = targetObject});

очень простой способ приблизиться к этому-поместить объект внутри другого объекта. возможно, это было слишком упрощенно, но это работает при работе с коллекциями и сингулярными объектами.

  public class StatusDTO
    {
        public int StatusId { get; set; }
        public string Name { get; set; }
        public DateTime Created { get; set; }
    }

    public class statusJasonModel
    {
        public StatusDTO status { get; set; }
    }

теперь, если вы поместите StatusDTO внутри объекта statusJsonModel и сериализуете его как Json. Он должен дать вам желаемый ответ.


у меня была аналогичная проблема в одном из моих проектов. Ниже приведен шаг, который я предпринял в решении проблемы.

1. Мой класс сущности

public class Product
    {
        [Key]
        public string Id { get; set; }
        public string Title { get; set; }
        public string Album { get; set; }
        public string Artist { get; set; }
        public string Genre { get; set; }

    }

2. Создал другой класс, который определен в этой форме.

    public class KindOfMedia
        {
            public KindOfMedia()
            {
                Product = new List<Product>();
            }
            public List<Product> Product { get; set; }
        }

3. Контроллер веб-API, который вернет json

            public HttpResponseMessage Products()
            {
                var kind = new KindOfMedia();
                kind.Products = new List<Product>();
                kind.Products.Add(new Product
                {
                    Id = Guid.NewGuid().ToString(),
                    Title = "I am A Winner",
                    Album = "",
                    Artist = "Project Fame",
                    Genre = "Contemporal"                
                });
                kind.Products.Add(new Product
                {
                    Id = Guid.NewGuid().ToString(),
                    Title = "Great Nation",
                    Album = "Oceans",
                    Artist = "Timi Dakolo",
                    Genre = "Gospel"
                });

                return Request.CreateResponse(HttpStatusCode.OK, kind);
            }

4. Добавьте эту строку кода в файл конфигурации WebApi в App_Start папка

     var json = config.Formatters.JsonFormatter;
                json.SerializerSettings.PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.None;

обратите внимание:Newtonsoft.формат JSON.PreserveReferencesHandling.Нет!--9-->, не сохранит ссылку типа сериализации

результирующий Json является

{
  "Musics": [
    {
      "Id": "bf9faeee-7c39-4c33-a0ea-f60333604061",
      "Title": "I am A Winner",
      "Album": "",
      "Artist": "Project Fame",
      "Genre": "Contemporal"
    },
    {
      "Id": "243edd32-7ba2-4ac4-8ab9-bba6399cb0a6",
      "Title": "Great Nation",
      "Album": "Oceans",
      "Artist": "Timi Dakolo",
      "Genre": "Gospel"
    }
  ]
}