19

我有一个使用 long as ID 的定制类。但是,当我使用 ajax 调用我的操作时,我的 ID 被截断并且丢失了最后 2 个数字,因为 javascript 在处理大数字时会丢失精度。我的解决方案是为我的 javascript 提供一个字符串,但 ID 必须在服务器端保持很长。

有没有办法将属性序列化为字符串?我正在寻找某种属性。

控制器

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}]
4

5 回答 5

28

您可能可以创建一个自定义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());
于 2013-06-28T17:15:38.217 回答
2

view model仅具有string属性的 a 怎么样,如下所示:

public class CustomerEntityViewModel
{
    public string ID { get; set; }
    public string Name { get; set; }
}

现在你只处理strings 并且JSON序列化问题消失了。

于 2013-06-28T16:27:15.230 回答
2

当我调用 json 序列化程序时,我可能只会创建一个匿名类型;

 JsonConvert.SerializeObject(new { instance.Name, instance.ID.ToString() } );

如果您的类有 20 个或其他字段,这将成为一个非常丑陋的解决方案,我会向ID名为lID只有字符串版本。

例如,有几个不同的属性可以实现这一点;

 public class CustomerEntity
 {
      [ScriptIgnore]
      public long _ID { get; set; }
      public string ID { get; set; }
      public string Name { get; set; }
 }

不会序列化_ID

于 2013-06-28T16:28:24.327 回答
1

根据您的情况,您可能会在 JSON 序列化期间使用 getter 和 setter 将属性伪装为字符串。

public class Money
{
    [JsonIgnore]
    public decimal Money { get; set; }

    [JsonProperty("money")]
    public string MoneyAsString
    {
        get { return Money.ToString("0.00"); }
        set { Money = decimal.Parse(value); }
    }
}
于 2017-03-31T18:22:26.967 回答
0

也许一个可行的解决方法是使用另一种类型的 ID?例如,您可以使用 GUID。使用 GUID,您将永远不会超出界限,而且我认为默认情况下这将被序列化为字符串。

于 2013-06-28T16:31:54.180 回答