C# 避免默认构造函数和公共属性设置器

C# 避免默认构造函数和公共属性设置器,c#,json.net,signalr,C#,Json.net,Signalr,我正在和信号器一起做一个项目,我有一些物体要穿过它。这些对象只是在我的后端代码中显式创建的,我真的希望能够对它们强制执行不变性和不变量。我遇到了一个问题,signer要求我(实际上是NewtonSoft.Json)在属性上有一个默认的、没有参数的构造函数和公共setter,以便它通过连接序列化和反序列化它们 下面是一个人为的例子: public class Message{ public string Text {get;set;} public int Awesomeness

我正在和信号器一起做一个项目,我有一些物体要穿过它。这些对象只是在我的后端代码中显式创建的,我真的希望能够对它们强制执行不变性和不变量。我遇到了一个问题,signer要求我(实际上是NewtonSoft.Json)在属性上有一个默认的、没有参数的构造函数和公共setter,以便它通过连接序列化和反序列化它们

下面是一个人为的例子:

public class Message{
    public string Text {get;set;}
    public int Awesomeness {get;set;}
}
我想要的是更符合这些原则的东西(它可能应该有只读的私有字段和getter-only属性,以便完全不可变,但是对于没有方法的POCO来说,这就足够了)

但我不能仅在属性的setter上使用过时属性

如果我真的想,我可以将“真实”对象从DTO表示中分离出来,并在它们之间进行转换,但我并没有真正准备好编写一系列样板文件来实现这一点,并引入另一层


是否有我忽略的东西,或者我只需要咬紧牙关解决它?

如果您的类没有公共无参数构造函数,但有一个带参数的公共构造函数,Json.NET将调用该构造函数,使用反射和缺少属性的默认值按名称将构造函数参数与JSON属性匹配。按名称匹配不区分大小写,除非有多个匹配项仅区分大小写,在这种情况下,匹配项区分大小写。因此,如果您只是这样做:

public class Message
{
    public string Text { get; private set; }
    public int Awesomeness { get; private set; }
    public Message(string text, int awesomeness)
    {
        if (awesomeness < 1 || awesomeness > 5)
        {
            throw new ArgumentOutOfRangeException("awesome");
        }
        this.Text = text;
        this.Awesomeness = awesomeness;
    }
}

另请参阅告诉Json.NET是否更喜欢非公共无参数构造函数而不是带有参数的单个公共构造函数。

不确定这是否可行,但如果将参数设置为可选参数,反序列化程序是否可行?您是否尝试过使用
[JsonProperty]
[Json构造函数]
属性?您可以将它们放在私有成员上,让Json.Net“查看”它们。您还可以为对象创建JSONConverter。看,你确定设定者需要公开吗?我以为你可以和私人二传手混在一起,只要他们在场?
[Obsolete("Bad! don't do this!")
public Message(){}
public class Message
{
    public string Text { get; private set; }
    public int Awesomeness { get; private set; }
    public Message(string text, int awesomeness)
    {
        if (awesomeness < 1 || awesomeness > 5)
        {
            throw new ArgumentOutOfRangeException("awesome");
        }
        this.Text = text;
        this.Awesomeness = awesomeness;
    }
}
public class Message
{
    public string Text { get; private set; }
    public int Awesomeness { get; private set; }

    public Message(string Text)
        : this(Text, 1)
    {
    }

    [JsonConstructor]
    public Message(string text, int awesomeness)
    {
        if (awesomeness < 1 || awesomeness > 5)
        {
            throw new ArgumentOutOfRangeException("awesome");
        }
        this.Text = text;
        this.Awesomeness = awesomeness;
    }
}