Как добавить пользовательский корневой узел при сериализации объекта с помощью 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"
}}
очень простой способ приблизиться к этому-поместить объект внутри другого объекта. возможно, это было слишком упрощенно, но это работает при работе с коллекциями и сингулярными объектами.
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"
}
]
}