.NET NewtonSoft JSON deserialize map to a different property name - json

I have following JSON string which is received from an external party.
{
"team":[
{
"v1":"",
"attributes":{
"eighty_min_score":"",
"home_or_away":"home",
"score":"22",
"team_id":"500"
}
},
{
"v1":"",
"attributes":{
"eighty_min_score":"",
"home_or_away":"away",
"score":"30",
"team_id":"600"
}
}
]
}
My mapping classes:
public class Attributes
{
public string eighty_min_score { get; set; }
public string home_or_away { get; set; }
public string score { get; set; }
public string team_id { get; set; }
}
public class Team
{
public string v1 { get; set; }
public Attributes attributes { get; set; }
}
public class RootObject
{
public List<Team> team { get; set; }
}
The question is that I don't like the Attributes class name and the attributes field names in the Team class. Instead, I want it to be named TeamScore and also to remove _ from the field names and give proper names.
JsonConvert.DeserializeObject<RootObject>(jsonText);
I can rename Attributes to TeamScore, but if I change the field name (attributes in the Team class), it won't deserialize properly and gives me null. How can I overcome this?

Json.NET - Newtonsoft has a JsonPropertyAttribute which allows you to specify the name of a JSON property, so your code should be:
public class TeamScore
{
[JsonProperty("eighty_min_score")]
public string EightyMinScore { get; set; }
[JsonProperty("home_or_away")]
public string HomeOrAway { get; set; }
[JsonProperty("score ")]
public string Score { get; set; }
[JsonProperty("team_id")]
public string TeamId { get; set; }
}
public class Team
{
public string v1 { get; set; }
[JsonProperty("attributes")]
public TeamScore TeamScores { get; set; }
}
public class RootObject
{
public List<Team> Team { get; set; }
}
Documentation: Serialization Attributes

If you'd like to use dynamic mapping, and don't want to clutter up your model with attributes, this approach worked for me
Usage:
var settings = new JsonSerializerSettings();
settings.DateFormatString = "YYYY-MM-DD";
settings.ContractResolver = new CustomContractResolver();
this.DataContext = JsonConvert.DeserializeObject<CountResponse>(jsonString, settings);
Logic:
public class CustomContractResolver : DefaultContractResolver
{
private Dictionary<string, string> PropertyMappings { get; set; }
public CustomContractResolver()
{
this.PropertyMappings = new Dictionary<string, string>
{
{"Meta", "meta"},
{"LastUpdated", "last_updated"},
{"Disclaimer", "disclaimer"},
{"License", "license"},
{"CountResults", "results"},
{"Term", "term"},
{"Count", "count"},
};
}
protected override string ResolvePropertyName(string propertyName)
{
string resolvedName = null;
var resolved = this.PropertyMappings.TryGetValue(propertyName, out resolvedName);
return (resolved) ? resolvedName : base.ResolvePropertyName(propertyName);
}
}

Adding to Jacks solution. I need to Deserialize using the JsonProperty and Serialize while ignoring the JsonProperty (or vice versa). ReflectionHelper and Attribute Helper are just helper classes that get a list of properties or attributes for a property. I can include if anyone actually cares. Using the example below you can serialize the viewmodel and get "Amount" even though the JsonProperty is "RecurringPrice".
/// <summary>
/// Ignore the Json Property attribute. This is usefule when you want to serialize or deserialize differently and not
/// let the JsonProperty control everything.
/// </summary>
/// <typeparam name="T"></typeparam>
public class IgnoreJsonPropertyResolver<T> : DefaultContractResolver
{
private Dictionary<string, string> PropertyMappings { get; set; }
public IgnoreJsonPropertyResolver()
{
this.PropertyMappings = new Dictionary<string, string>();
var properties = ReflectionHelper<T>.GetGetProperties(false)();
foreach (var propertyInfo in properties)
{
var jsonProperty = AttributeHelper.GetAttribute<JsonPropertyAttribute>(propertyInfo);
if (jsonProperty != null)
{
PropertyMappings.Add(jsonProperty.PropertyName, propertyInfo.Name);
}
}
}
protected override string ResolvePropertyName(string propertyName)
{
string resolvedName = null;
var resolved = this.PropertyMappings.TryGetValue(propertyName, out resolvedName);
return (resolved) ? resolvedName : base.ResolvePropertyName(propertyName);
}
}
Usage:
var settings = new JsonSerializerSettings();
settings.DateFormatString = "YYYY-MM-DD";
settings.ContractResolver = new IgnoreJsonPropertyResolver<PlanViewModel>();
var model = new PlanViewModel() {Amount = 100};
var strModel = JsonConvert.SerializeObject(model,settings);
Model:
public class PlanViewModel
{
/// <summary>
/// The customer is charged an amount over an interval for the subscription.
/// </summary>
[JsonProperty(PropertyName = "RecurringPrice")]
public double Amount { get; set; }
/// <summary>
/// Indicates the number of intervals between each billing. If interval=2, the customer would be billed every two
/// months or years depending on the value for interval_unit.
/// </summary>
public int Interval { get; set; } = 1;
/// <summary>
/// Number of free trial days that can be granted when a customer is subscribed to this plan.
/// </summary>
public int TrialPeriod { get; set; } = 30;
/// <summary>
/// This indicates a one-time fee charged upfront while creating a subscription for this plan.
/// </summary>
[JsonProperty(PropertyName = "SetupFee")]
public double SetupAmount { get; set; } = 0;
/// <summary>
/// String representing the type id, usually a lookup value, for the record.
/// </summary>
[JsonProperty(PropertyName = "TypeId")]
public string Type { get; set; }
/// <summary>
/// Billing Frequency
/// </summary>
[JsonProperty(PropertyName = "BillingFrequency")]
public string Period { get; set; }
/// <summary>
/// String representing the type id, usually a lookup value, for the record.
/// </summary>
[JsonProperty(PropertyName = "PlanUseType")]
public string Purpose { get; set; }
}

Expanding Rentering.com's answer, in scenarios where a whole graph of many types is to be taken care of, and you're looking for a strongly typed solution, this class can help, see usage (fluent) below. It operates as either a black-list or white-list per type. A type cannot be both (Gist - also contains global ignore list).
public class PropertyFilterResolver : DefaultContractResolver
{
const string _Err = "A type can be either in the include list or the ignore list.";
Dictionary<Type, IEnumerable<string>> _IgnorePropertiesMap = new Dictionary<Type, IEnumerable<string>>();
Dictionary<Type, IEnumerable<string>> _IncludePropertiesMap = new Dictionary<Type, IEnumerable<string>>();
public PropertyFilterResolver SetIgnoredProperties<T>(params Expression<Func<T, object>>[] propertyAccessors)
{
if (propertyAccessors == null) return this;
if (_IncludePropertiesMap.ContainsKey(typeof(T))) throw new ArgumentException(_Err);
var properties = propertyAccessors.Select(GetPropertyName);
_IgnorePropertiesMap[typeof(T)] = properties.ToArray();
return this;
}
public PropertyFilterResolver SetIncludedProperties<T>(params Expression<Func<T, object>>[] propertyAccessors)
{
if (propertyAccessors == null)
return this;
if (_IgnorePropertiesMap.ContainsKey(typeof(T))) throw new ArgumentException(_Err);
var properties = propertyAccessors.Select(GetPropertyName);
_IncludePropertiesMap[typeof(T)] = properties.ToArray();
return this;
}
protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
{
var properties = base.CreateProperties(type, memberSerialization);
var isIgnoreList = _IgnorePropertiesMap.TryGetValue(type, out IEnumerable<string> map);
if (!isIgnoreList && !_IncludePropertiesMap.TryGetValue(type, out map))
return properties;
Func<JsonProperty, bool> predicate = jp => map.Contains(jp.PropertyName) == !isIgnoreList;
return properties.Where(predicate).ToArray();
}
string GetPropertyName<TSource, TProperty>(
Expression<Func<TSource, TProperty>> propertyLambda)
{
if (!(propertyLambda.Body is MemberExpression member))
throw new ArgumentException($"Expression '{propertyLambda}' refers to a method, not a property.");
if (!(member.Member is PropertyInfo propInfo))
throw new ArgumentException($"Expression '{propertyLambda}' refers to a field, not a property.");
var type = typeof(TSource);
if (!type.GetTypeInfo().IsAssignableFrom(propInfo.DeclaringType.GetTypeInfo()))
throw new ArgumentException($"Expresion '{propertyLambda}' refers to a property that is not from type '{type}'.");
return propInfo.Name;
}
}
Usage:
var resolver = new PropertyFilterResolver()
.SetIncludedProperties<User>(
u => u.Id,
u => u.UnitId)
.SetIgnoredProperties<Person>(
r => r.Responders)
.SetIncludedProperties<Blog>(
b => b.Id)
.Ignore(nameof(IChangeTracking.IsChanged)); //see gist

I am using JsonProperty attributes when serializing but ignoring them when deserializing using this ContractResolver:
public class IgnoreJsonPropertyContractResolver: DefaultContractResolver
{
protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
{
var properties = base.CreateProperties(type, memberSerialization);
foreach (var p in properties) { p.PropertyName = p.UnderlyingName; }
return properties;
}
}
The ContractResolver just sets every property back to the class property name (simplified from Shimmy's solution). Usage:
var airplane= JsonConvert.DeserializeObject<Airplane>(json,
new JsonSerializerSettings { ContractResolver = new IgnoreJsonPropertyContractResolver() });

Also if you want to ignore something use this
[JsonIgnore]
public int Id { get; set; }
[JsonProperty("id")]
Public string real_id { get; set; }

Related

Api Controller: Json decapitalizes the names of properties

I have an api controller in my webcore application:
[Route("api/[controller]")]
public class DataController : Controller
{
protected ApplicationDbContext dbContext;
public DataController(ApplicationDbContext dc)
{
dbContext = dc;
}
[HttpGet("Categories")]
public List<Category> GetCategories()
{
var l = dbContext.Categories.OrderBy(c => c.Name).ToList();
return l;
}
}
And the class:
public class Category
{
public long Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
}
When I Invoke the controller action to get the categories, in the response the name of properties are all decapitalized. That is:
Id becomes id,
Name becomes name,
Description becomes description.
**Edit:
I have tried also:
[HttpGet("Test")]
public IActionResult Test()
{
var l = dbContext.Categories.OrderBy(c => c.Name).ToList();
return Json(l);
}
And still the properties are all decapitalized
/// <summary>
/// Welcome Note Message
/// </summary>
/// <returns>In a Json Format</returns>
public JsonResult WelcomeNote()
{
Category cs = new Category();
cs.Id = 123456;
cs.Name = "ExampleName";
cs.Description = "Abcd";
return Json(cs, JsonRequestBehavior.AllowGet);
}
This, I am getting from above code which you want I guess
Refer this for more good Examples

JsonProperty WebApi request and response models

I have an API that talks to another API.
The response model looks something like this:
public class AddressResponseModel
{
public string Id { get; set; }
public string SaveAs { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Phone { get; set; }
public string Address1 { get; set; }
public string Address2 { get; set; }
public string City { get; set; }
public string County { get; set; }
public string Country { get; set; }
public string PostCode { get; set; }
}
So, I need to send this to another API. I don't really want to play around with the response in JavaScript, I would just like to send it as it is to my endpoint and let the server handle its factorization.
So, I tried to do this:
public class AddressBindingModel
{
[Required]
[JsonProperty("address_1")]
public string Address1 { get; set; }
[JsonProperty("address_2")]
public string Address2 { get; set; }
[Required]
[JsonProperty("city")]
public string City { get; set; }
[Required]
[JsonProperty("county")]
public string County { get; set; }
[Required]
[JsonProperty("postcode")]
public string PostCode { get; set; }
[Required]
[JsonProperty("country")]
public string Country { get; set; }
[JsonProperty("save_as")]
public string SaveAs { get; set; }
}
but the problem with that is that it expects the json to follow to same property format.
How can I get it to expect my unmodified response model, but output the JSON with the underscores?
To clarify, I will post my model like this:
{
address1: '123',
address2: 'Some street',
city: 'London',
county: 'London',
country: 'GB',
saveAs: 'Home'
}
and my API will then send this to another API like this:
{
address_1: '123',
address_2: 'Some street',
city: 'London',
county: 'London',
country: 'GB',
save_as: 'Home'
}
If you want to use the same classes to automatically generate JSON with different property names, without having to write a custom JsonConverter for each one, you're going to need to create your own custom ContractResolver, for instance:
Json.NET provides CamelCasePropertyNamesContractResolver.
This Answer has a prototype PascalCaseToUnderscoreContractResolver.
If you have a deterministic way to map all .Net property names to the appropriate property names for a given usage context (post or get-from-api), you can create a contract resolver like one of the above.
If, however, there's no general rule for mapping .Net property names for JSON property names, and each context may require some per-property customization, you could create your own ContractResolver that applies in a specific named context, and your own System.Attribute that supplies a JSON context name and property name to use in this context. I.e.:
[System.AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = true, Inherited = true)]
public class JsonConditionalNameAttribute : System.Attribute
{
readonly string contextName;
readonly string propertyName;
public string ContextName { get { return contextName; } }
public string PropertyName { get { return propertyName; } }
public JsonConditionalNameAttribute(string contextName, string propertyName)
{
this.contextName = contextName;
this.propertyName = propertyName;
}
}
public class ConditionalNameContractResolver : DefaultContractResolver
{
readonly string contextName;
public string ContextName { get { return contextName; } }
public ConditionalNameContractResolver(string contextName)
: base()
{
if (string.IsNullOrEmpty(contextName))
throw new ArgumentNullException();
if (string.IsNullOrEmpty(contextName))
throw new ArgumentException();
this.contextName = contextName;
}
protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
{
var jProperty = base.CreateProperty(member, memberSerialization);
var attrs = jProperty.AttributeProvider.GetAttributes(typeof(JsonConditionalNameAttribute), true)
.Cast<JsonConditionalNameAttribute>()
.Where(a => a.ContextName == ContextName)
.Select(a => a.PropertyName)
.Distinct()
.ToList();
if (attrs.Count == 1)
{
jProperty.PropertyName = attrs[0];
}
else if (attrs.Count > 1)
{
throw new JsonSerializationException(string.Format("Multiple conditional property attributes found for \"{0}\" in in context \"{1}\": \"{2}\"", jProperty, contextName, String.Join(",", attrs)));
}
return jProperty;
}
}
Then your binding model would look something like:
public static class AddressBindingModelContexts
{
public const string Post = "post";
public const string GetFromApi = "getFromApi";
}
public class AddressBindingModel
{
[JsonConditionalName(AddressBindingModelContexts.GetFromApi, "address_1")]
[JsonConditionalName(AddressBindingModelContexts.Post, "address1")]
public string Address1 { get; set; }
[JsonConditionalName(AddressBindingModelContexts.GetFromApi, "address_2")]
[JsonConditionalName(AddressBindingModelContexts.Post, "address2")]
public string Address2 { get; set; }
[JsonProperty("city")]
public string City { get; set; }
[JsonProperty("county")]
public string County { get; set; }
[JsonProperty("postcode")]
public string PostCode { get; set; }
[JsonProperty("country")]
public string Country { get; set; }
[JsonConditionalName(AddressBindingModelContexts.GetFromApi, "save_as")]
[JsonConditionalName(AddressBindingModelContexts.Post, "saveAs")]
public string SaveAs { get; set; }
}
To test:
var jsonFromApi = GetJsonFromApi();
var postContract = new ConditionalNameContractResolver(AddressBindingModelContexts.Post);
var getFromApiContract = new ConditionalNameContractResolver(AddressBindingModelContexts.GetFromApi);
var model = JsonConvert.DeserializeObject<AddressBindingModel>(jsonFromApi, new JsonSerializerSettings { ContractResolver = getFromApiContract });
var postJson = JsonConvert.SerializeObject(model, Formatting.Indented, new JsonSerializerSettings { ContractResolver = postContract });
Debug.WriteLine(postJson); // Verify the postJson has the necessary properties and data.
To change the contract resolver for all results returned from Web API, see JSON and XML Serialization in ASP.NET Web API: Camel Casing. To use a custom contract resolver when returning results from a specific Web Api call, see Customize Json result in Web API.

How to convert json dynamic object to c# entity

When I make mvc ajax json post applicaiton, there is a trouble to convert json dynamic object to entity.
In my app, movie is a business entity, json object has row status property than movie entity. When json data is posted to mvc server side, it can be converted to dynamic object, everyting is ok in this stage. But after handling some logic to each row status, it is needed to convert dynamic object to movie business entity, then begin database transaction logic. But there is a troulbe even I try different method to cast the object.
please did someone use the same cast method? thanks your advice or reply.
public class movie
{
public int id
{
get;
set;
}
public string title
{
get;
set;
}
}
/// <summary>
/// Convert Json Object to Entity
/// </summary>
/// <param name="id">ajax post value
/// format: {"id": "{\"id\": 1, \"title\": \"sharlock\", \"RowStatus\": \"deleted\"}"}
/// </param>
[AllowAnonymous]
[HttpPost]
public void DoJsonSimple(string id)
{
string title;
var entity = Newtonsoft.Json.JsonConvert.DeserializeObject<dynamic>(id);
//*** entity is dynamic object
//*** entity.id, entity.title and entity.RowStauts can be accessed.
int first = entity.id;
var status = entity.RowStatus;
if (status == "deleted")
{
//*** m1 is null
//*** m1.title can not be accessed
movie m1 = entity as movie;
title = m1.title;
//*** m2 is an empty object
//*** m2.id is 0, m2.title is null
var m2 = AutoMapperHelper<dynamic, movie>.AutoConvertDynamic(entity);
title = m2.title;
//*** Exception: Object must implement IConvertible.
var m3 = EmitMapper.EMConvert.ChangeTypeGeneric<dynamic, movie>(entity);
title = m3.title;
}
}
Just create another class for the rows.
public class Request
{
[JsonProperty("id")]
public string Json { get; set; }
}
public class Movie
{
[JsonProperty("id")]
public int Id { get; set; }
[JsonProperty("title")]
public string Title { get; set; }
}
// either this for variant 1...
public class Row
{
public string RowStatus { get; set; }
}
// or that for variant 2...
public class MovieRow : Movie
{
public string RowStatus { get; set; }
}
[AllowAnonymous]
[HttpPost]
public void DoJsonSimple_Variant1(string id)
{
var json = JsonConvert.DeserializeObject<Request>(id).Json;
var entity = JsonConvert.DeserializeObject<MovieRow>(json);
var row = JsonConvert.DeserializeObject<Row>(json);
switch (row.RowStatus)
{
case "deleted":
// delete entity
break;
// ...
}
// ...
}
[AllowAnonymous]
[HttpPost]
public void DoJsonSimple_Variant2(string id)
{
var json = JsonConvert.DeserializeObject<Request>(id).Json;
var row = JsonConvert.DeserializeObject<MovieRow>(json);
var entity = (Movie)row;
switch (row.RowStatus)
{
case "deleted":
// delete entity
break;
// ...
}
// ...
}

Get images from wordpress post with json in windows phone

I would like to get Images from a wordpress Blog. I would start only with one post not with all the posts images.
I am using this code. It works to get the title, excerpt, url... But I cant get images :
namespace WpWordpressJson
{
public class MainViewModel : INotifyPropertyChanged
{
public MainViewModel()
{
this.Items = new ObservableCollection<ItemViewModel>();
}
/// <summary>
/// A collection for ItemViewModel objects.
/// </summary>
public ObservableCollection<ItemViewModel> Items { get; private set; }
private string _sampleProperty = "Sample Runtime Property Value";
/// <summary>
/// Sample ViewModel property; this property is used in the view to display its value using a Binding
/// </summary>
/// <returns></returns>
public string SampleProperty
{
get
{
return _sampleProperty;
}
set
{
if (value != _sampleProperty)
{
_sampleProperty = value;
NotifyPropertyChanged("SampleProperty");
}
}
}
public bool IsDataLoaded
{
get;
private set;
}
/// <summary>
/// Creates and adds a few ItemViewModel objects into the Items collection.
/// </summary>
public void LoadData()
{
WebRequest.RegisterPrefix("http://automaticband.es/bio/", WebRequestCreator.ClientHttp);
Uri serviceUri = new Uri("http://automaticband.es/bio/?json=get_recent_posts");
WebClient downloader = new WebClient();
downloader.OpenReadCompleted += new OpenReadCompletedEventHandler(downloader_OpenReadCompleted);
downloader.OpenReadAsync(serviceUri);
}
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(String propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (null != handler)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
void downloader_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
{
if (e.Error == null)
{
try
{
Stream responseStream = e.Result;
DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(Posts));
Posts response = (Posts)ser.ReadObject(responseStream);
if (response.posts != null && response.posts.Count > 0)
{
foreach (Post post in response.posts)
{
this.Items.Add(new ItemViewModel() { LineOne = post.title, LineTwo = post.excerpt });
}
}
}
catch (Exception x)
{
return;
}
this.IsDataLoaded = true;
}
}
}
[DataContract]
public class Post
{
[DataMember]
public int id;
[DataMember]
public string type;
[DataMember]
public string slug;
[DataMember]
public string title;
[DataMember]
public string content;
[DataMember]
public string excerpt;
}
[DataContract]
public class Posts
{
[DataMember]
public int count;
[DataMember]
public int count_total;
[DataMember]
public List<Post> posts;
}
I got it from this site:
http://kevinashley.com/connect-windows-phone-7-apps-to-wordpress-using-json/
Thank you for all
You are missing the DataMember for thumbnails in Post. Here you can find a full class for WordPress JSON API: http://msicc.net/?p=2929
Hope this helps :-)

MVC3 JSON Serialization: How to control the property names?

I want to serialize a simple object to JSON:
public class JsonTreeNode
{
[DataMember(Name = "title")]
public string Title { get; set; }
[DataMember(Name = "isFolder")]
public bool IsFolder { get; set; }
[DataMember(Name = "key")]
public string Key { get; set; }
[DataMember(Name = "children")]
public IEnumerable<JsonTreeNode> Children { get; set; }
[DataMember(Name = "select")]
public bool SelectedOnInit { get; set; }
}
But whenever I do it:
return Json(tree, JsonRequestBehavior.AllowGet);
The property names are not as specified in the [DataMember] section, but similar to the ones defined directly in the class e.g. in the case of SelectOnInit it is not select but SelectOnInit.
What am I doing wrong?
I solved the problem by using the technique provided in the answer in this question:
ASP.NET MVC: Controlling serialization of property names with JsonResult
Here is the class I made:
/// <summary>
/// Similiar to <see cref="JsonResult"/>, with
/// the exception that the <see cref="DataContract"/> attributes are
/// respected.
/// </summary>
/// <remarks>
/// Based on the excellent stackoverflow answer:
/// https://stackoverflow.com/a/263416/1039947
/// </remarks>
public class JsonDataContractActionResult : ActionResult
{
/// <summary>
/// Initializes a new instance of the class.
/// </summary>
/// <param name="data">Data to parse.</param>
public JsonDataContractActionResult(Object data)
{
Data = data;
}
/// <summary>
/// Gets or sets the data.
/// </summary>
public Object Data { get; private set; }
/// <summary>
/// Enables processing of the result of an action method by a
/// custom type that inherits from the ActionResult class.
/// </summary>
/// <param name="context">The controller context.</param>
public override void ExecuteResult(ControllerContext context)
{
if (context == null)
throw new ArgumentNullException("context");
var serializer = new DataContractJsonSerializer(Data.GetType());
string output;
using (var ms = new MemoryStream())
{
serializer.WriteObject(ms, Data);
output = Encoding.UTF8.GetString(ms.ToArray());
}
context.HttpContext.Response.ContentType = "application/json";
context.HttpContext.Response.Write(output);
}
}
Usage:
public ActionResult TestFunction()
{
var testObject = new TestClass();
return new JsonDataContractActionResult(testObject);
}
I also had to modify the initial class:
// -- The DataContract property was added --
[DataContract]
public class JsonTreeNode
{
[DataMember(Name = "title")]
public string Title { get; set; }
[DataMember(Name = "isFolder")]
public bool IsFolder { get; set; }
[DataMember(Name = "key")]
public string Key { get; set; }
[DataMember(Name = "children")]
public IEnumerable<JsonTreeNode> Children { get; set; }
[DataMember(Name = "select")]
public bool SelectedOnInit { get; set; }
}
This is a solution that uses newtonsoft Json.net (for performance concerned)
I've found part of the solution here and on SO
public class JsonNetResult : ActionResult
{
public Encoding ContentEncoding { get; set; }
public string ContentType { get; set; }
public object Data { get; set; }
public JsonSerializerSettings SerializerSettings { get; set; }
public Formatting Formatting { get; set; }
public JsonNetResult(object data, Formatting formatting)
: this(data)
{
Formatting = formatting;
}
public JsonNetResult(object data):this()
{
Data = data;
}
public JsonNetResult()
{
Formatting = Formatting.None;
SerializerSettings = new JsonSerializerSettings();
}
public override void ExecuteResult(ControllerContext context)
{
if (context == null)
throw new ArgumentNullException("context");
var response = context.HttpContext.Response;
response.ContentType = !string.IsNullOrEmpty(ContentType)
? ContentType
: "application/json";
if (ContentEncoding != null)
response.ContentEncoding = ContentEncoding;
if (Data == null) return;
var writer = new JsonTextWriter(response.Output) { Formatting = Formatting };
var serializer = JsonSerializer.Create(SerializerSettings);
serializer.Serialize(writer, Data);
writer.Flush();
}
}
So that in my controller, I can do that
return new JsonNetResult(result);
In my model, I can now have:
[JsonProperty(PropertyName = "n")]
public string Name { get; set; }
Note that now, you have to set the JsonPropertyAttribute to every property you want to serialize.