私は、ID として long を使用するカスタム クラスを持っています。ただし、Ajax を使用してアクションを呼び出すと、JavaScript は大きな数値を処理するときに精度を失うため、ID が切り捨てられ、最後の 2 つの数字が失われます。私の解決策は、JavaScript に文字列を与えることですが、ID はサーバー側で long のままにする必要があります。
プロパティを文字列としてシリアル化する方法はありますか? 何らかの属性を探しています。
コントローラ
public class CustomersController : ApiController
{
public IEnumerable<CustomerEntity> Get()
{
yield return new CustomerEntity() { ID = 1306270928525862486, Name = "Test" };
}
}
モデル
public class CustomerEntity
{
public long ID { get; set; }
public string Name { get; set; }
}
JSON 結果
[{"Name":"Test","ID":1306270928525862400}]
ベストアンサー1
おそらくカスタムを作成してJsonConverter
、それを自分のプロパティに適用できるでしょう。
以下は例です(注記: この API はこれまで使用したことがないので、おそらくさらに改善される可能性がありますが、以下から大まかな概要がわかると思います):
public class Person
{
[JsonConverter(typeof(IdToStringConverter))]
public long ID { get; set; }
public string Name { get; set; }
}
public class IdToStringConverter : JsonConverter
{
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
JToken jt = JValue.ReadFrom(reader);
return jt.Value<long>();
}
public override bool CanConvert(Type objectType)
{
return typeof(System.Int64).Equals(objectType);
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
serializer.Serialize(writer, value.ToString());
}
}
Web API アクション:
public Person Post([FromBody]Person person)
{
return person;
}
リクエスト:
POST http://asdfasdf/api/values HTTP/1.1
Host: servername:9095
Connection: Keep-Alive
Content-Type: application/json
Content-Length: 42
{"ID":"1306270928525862400","Name":"Mike"}
応答:
HTTP/1.1 200 OK
Content-Length: 42
Content-Type: application/json; charset=utf-8
Server: Microsoft-HTTPAPI/2.0
Date: Fri, 28 Jun 2013 17:02:18 GMT
{"ID":"1306270928525862400","Name":"Mike"}
編集:
プロパティを属性で装飾したくない場合は、代わりに Converters コレクションに追加することができます。例:
config.Formatters.JsonFormatter.SerializerSettings.Converters.Add(new IdToStringConverter());