I am trying to output JSON directly in my Razor view. The object being serialized is IEnumerable<ItemDto> (see definition below). I want to serialize it to identical JSON that would be returned from an ApiController. Here is what I have tried:
- When using
@Json.Encode(theValue), it ignores theDataMember, so the properties get the wrong names (uppercase first letter). - When using
DataContractJsonSerializer(and castingtheIEnumerable<ItemDto>toIList<ItemDto>), it outputs theImageDto.Sizesas[{ Key: 'foo', Value: <object> }], but the ApiController correctly does{ 'foo': <object> }.
Here are my classes:
[DataContract]
public class ItemDto
{
[DataMember(Name = "id")]
public int Id { get; set; }
[DataMember(Name = "title")]
public string Title { get; set; }
[DataMember(Name = "image")]
public ImageDto Image { get; set; }
[DataMember(Name = "price")]
public decimal Price { get; set; }
}
[DataContract]
public class ImageDto
{
[DataMember(Name = "id")]
public Guid Id { get; set; }
[DataMember(Name = "sizes")]
public Dictionary<String, ImageSizeDto> Sizes { get; set; }
}
[DataContract]
public class ImageSizeDto
{
[DataMember(Name = "url")]
public string Url { get; set; }
[DataMember(Name = "w")]
public int Width { get; set; }
[DataMember(Name = "h")]
public int Height { get; set; }
}
The objective is to avoid a separate GET request for data that is necessary on almost every page.
Desired JSON:
[{"id":6,
"title":"Foo bar baz",
"image":
{"id":"fb2a3b4a-5ae5-4d9d-baff-72e107aa6e9c",
"sizes":
{"Original": {"url":"http://example.com/a", "w":-1, "h":-1},
"Thumbnail": {"url":"http://example.com/b", "w":130, "h":73},
"LargeThumbnail": {"url":"http://example.com/c", "w":220,"h":124},
"Popup": {"url":"http://example.com/d", "w":256, "h":256},
"FullWidth": {"url":"http://example.com/e", "w":930, "h":524}}},
"price":79}]
You could use Json.NET:
outputs:
Note that in the ASP.NET MVC 4 RTM Json.Net will be the default serialzier. Until then simply swap the built-in serializer with Json.NET as illustrated in the Scott Hanselman’s blog post.