問題描述
JsonResult 相當於 [DataMember(Name="Test")] (JsonResult equivalent to [DataMember(Name="Test")])
我有這樣的方法:
public JsonResult Layar(string countryCode, string timestamp, string userId,
string developerId, string layarName, double radius,
double lat, double lon, double accuracy)
{
LayarModel model = new LayarModel(lat, lon, radius);
return Json(model, JsonRequestBehavior.AllowGet);
}
它返回這個對象:
public class LayarModel
{
private List<HotSpot> _hotSpots = new List<HotSpot>();
public List<HotSpot> HotSpots { get { return _hotSpots; } set { _hotSpots = value; } }
public string Name { get; set; }
public int ErrorCode { get; set; }
public string ErrorString { get; set; }
}
我希望 JSON 是
{"hotspots": [{
"distance": 100,
"attribution": "The Location of the Layar Office",
"title": "The Layar Office",
"lon": 4884339,
"imageURL": http:\/\/custom.layar.nl\/layarimage.jpeg,
"line4": "1019DW Amsterdam",
"line3": "distance:%distance%",
"line2": "Rietlandpark 301",
"actions": [],
"lat": 52374544,
"type": 0,
"id": "test_1"}],
"layer": "snowy4",
"errorString": "ok",
"morePages": false,
"errorCode": 0,
"nextPageKey": null
}
在返回的類中所有內容都大寫(HotSpots
而不是 hotspots
)。
我已經嘗試過 DataContract 和 DataMembers(Name= “測試”),但這不起作用。有什麼建議嗎?
參考解法
方法 1:
JsonResult() uses JavaScriptSerializer internally for serialization, and it seems it doesn't support defining the serialized property names using attributes.
DataContractJsonSerializer supports this, so that may be a way to go.
Some links that may be useful:
- JavaScriptSerializer.Deserialize ‑ how to change field names : JavaScriptSerializer.Deserialize ‑ how to change field names
- DataContractJsonSerializer Versus JavaScriptSerializer : Changing Field Names: http://publicityson.blogspot.com/2010/06/datacontractjsonserializer‑versus.html
方法 2:
I would also recommend installing json.NET but the rest is a lot easier. Below is an extension method I am using in my current application to provide better reuse, feel free to adapt it to your needs, but it should do what you need right out of the box.
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()
{
SerializerSettings = new JsonSerializerSettings
{
//http://odetocode.com/blogs/scott/archive/2013/03/25/asp‑net‑webapi‑tip‑3‑camelcasing‑json.aspx
#if DEBUG
Formatting = Formatting.Indented, //Makes the outputted Json easier reading by a human, only needed in debug
#endif
ContractResolver = new CamelCasePropertyNamesContractResolver() //Makes the default for properties outputted by Json to use camelCaps
};
}
public override void ExecuteResult(ControllerContext context)
{
if (context == null)
throw new ArgumentNullException("context");
HttpResponseBase response = context.HttpContext.Response;
response.ContentType = !string.IsNullOrEmpty(ContentType)
? ContentType
: "application/json";
if (ContentEncoding != null)
response.ContentEncoding = ContentEncoding;
if (Data != null)
{
JsonTextWriter writer = new JsonTextWriter(response.Output) {Formatting = Formatting};
JsonSerializer serializer = JsonSerializer.Create(SerializerSettings);
serializer.Serialize(writer, Data);
writer.Flush();
}
}
}
public static class JsonNetExtenionMethods
{
public static ActionResult JsonNet(this Controller controller, object data)
{
return new JsonNetResult() {Data = data};
}
public static ActionResult JsonNet(this Controller controller, object data, string contentType)
{
return new JsonNetResult() { Data = data, ContentType = contentType };
}
public static ActionResult JsonNet(this Controller controller, object data, Formatting formatting)
{
return new JsonNetResult() {Data = data, Formatting = formatting};
}
}
Here's an example of using it.
public JsonNetResult Layar(string countryCode, string timestamp, string userId,
string developerId, string layarName, double radius,
double lat, double lon, double accuracy)
{
LayarModel model = new LayarModel(lat, lon, radius);
return this.JsonNet(model);
}
The part to note that solves your problem specifically is when the ContractResolver
on the JsonSerializerSettings
is set to use new CamelCasePropertyNamesContractResolver()
This way you never have to set custom naming again.
(by Andy、CGK、Nick Albrecht)