相关疑难解决方法(0)

Json 反序列化受保护的属性

我有一个类属性集,并在构造函数中固定,下面的示例是一个Guid.NewGuid()..

理由是只允许类在创建时填充..所以它在构造函数中设置,并且只标记为get;- 工作正常,直到我序列化/反序列化为 Json。

似乎因为没有set;反序列化失败..并且构造函数介入并创建了一个新的guid

我已经尝试过内部、私有和受保护的 set .. 但所有结果都导致属性的再生,我可以让它工作的唯一方法是将 Id 标记为{get;set;}

class Foo
{
    public Foo() => Id = Guid.NewGuid().ToString();
    public string Id { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

这意味着您可以简单地执行以下操作:

var obj = new Foo();
obj.Id = "Any Old Rubbish";
Run Code Online (Sandbox Code Playgroud)

有没有办法解决这个问题?

短样本:

class Program
{
    static void Main()
    {
        var obj = new Foo();
        Console.WriteLine(obj.Id);

        var serialize = JsonConvert.SerializeObject(obj);
        var deserialize = JsonConvert.DeserializeObject<Foo>(serialize);
        Console.WriteLine(deserialize.Id);

        Console.ReadLine();
    }
}

class Foo
{
    public Foo() => …
Run Code Online (Sandbox Code Playgroud)

c# json.net

6
推荐指数
1
解决办法
2678
查看次数

避免使用默认构造函数和公共属性setter

我正在研究SignalR的一个项目,我有一些我将要通过它的对象.这些对象只在我的后端代码中显式创建,我真的希望能够对它们强制实现不变性和不变量.我遇到了SignalR要求我(好吧,实际上是NewtonSoft.Json)的问题,在我的属性上有一个默认的,无参数的构造函数和公共setter,以便它通过网络序列化和反序列化它们.

这是一个人为的例子:

public class Message{
    public string Text {get;set;}
    public int Awesomeness {get;set;}
}
Run Code Online (Sandbox Code Playgroud)

我想要的是,更多的是这些内容(它应该只有readonly私有字段和getter-only属性完全不可变,但对于只有POCO而没有方法的东西,足够好)

public class Message {
    public string Text {get;private set;}
    public int Awesomeness {get;private set;}
    public Message( string msg, int awesome){
        if (awesome < 1 || awesome > 5){
            throw new ArgumentOutOfRangeException("awesome");
        }
        Text = msg;
        Awesomeness = awesome;
    }
}
Run Code Online (Sandbox Code Playgroud)

但是,如果我这样做,我的对象不能被SignalR .NET客户端库反序列化.我可以在那里查找一个默认构造函数,然后公开我的setter,但是我必须记住不要在我的代码中使用它们,并确保团队中没有其他人在不理解的情况下使用它们.

我已经开始尝试这样做,将默认构造函数标记为永远不应该显式使用的东西:

[Obsolete("Bad! don't do this!")
public Message(){}
Run Code Online (Sandbox Code Playgroud)

但是我不能仅仅在属性的setter上使用Obsolete属性.

如果我真的想要,我可以从DTO表示中分离出"真实"对象并在它们之间进行转换,但是我真的很兴奋写一堆样板来做这件事并引入另一层.

有什么我忽略的,或者我只需要咬紧牙关并处理它?

c# json.net signalr

2
推荐指数
1
解决办法
969
查看次数

如何使用 Json.Net 将缺少的属性反序列化为 F# 记录中的空列表而不是 null

考虑包含如下列表值的 F# 记录:

type MyRecord = {
    Name: string
    SomeList: string list
}
Run Code Online (Sandbox Code Playgroud)

Netwonsoft.Json.JsonConvert当 JSON 不包含记录的列表值的属性时,使用将 JSON 反序列化为Values该记录将导致反序列化的记录具有null列表的值而不是空列表[]

那是,

open Newtonsoft.Json
JsonConvert.DeserializeObject<MyRecord>("""{ "Name": "Some name"}""" ) |> printfn "%A"
// Gives: { Name = "Some name"; SomeList = null; }
Run Code Online (Sandbox Code Playgroud)

如何反序列化 usingNetwonsoft.Json以使列表初始化为空列表?例如:

{ Name = "Some name"; SomeList = []; }
Run Code Online (Sandbox Code Playgroud)

f# json.net

2
推荐指数
1
解决办法
234
查看次数

Newtonsoft json将缺少int值的序列反序列化为空值而不是零

可以这样调整JsonSerializerSettings吗?

(我猜不是)但仍有一些希望,因为我对他们的API不是很有经验.

默认情况下,我尝试丢失的所有设置都反序列化为0或导致异常.

   {
      "defaultCaptionLineNum": 6,
      "worksheets": {
        "0": { "name": "Ws1", "caption_ln": 6 },
        "1": { "name": "Ws2", "caption_ln": null },
        "2": { "name": "Ws3" },
        "3": { "name": "Ws4", "caption_ln": 5 },
      }
}
Run Code Online (Sandbox Code Playgroud)

目前默认情况下,Ws3的标题行(caption_ln)计算为0,我希望将其计算为null(如Ws2中所示).

我正在使用

jObject.ToObject<MyClass>(JsonSerializer.Create(settings));
Run Code Online (Sandbox Code Playgroud)

从JSON获取带有工作表(Ws)信息的对象(在没有序列化器的情况下尝试了它)

和任何变化Include,并Ignore在这里不作jObject在反序列化JSON缺少整数不同(与抛误差除外马上遗漏值)

var settings = new JsonSerializerSettings
{
NullValueHandling = NullValueHandling.Include,
MissingMemberHandling = MissingMemberHandling.Ignore
};
Run Code Online (Sandbox Code Playgroud)

其他串行器设置似乎无关紧要.

UPD:MyObject MyClass的列表.

public class MyClass
{
    public class WorkSheet
    {
        [JsonProperty("name")]
        string wsName;

        [JsonProperty("caption_ln")]
        int? captionLineNumber;

        public WorkSheet(string name, …
Run Code Online (Sandbox Code Playgroud)

c# json.net

1
推荐指数
1
解决办法
834
查看次数

标签 统计

json.net ×4

c# ×3

f# ×1

signalr ×1