C# 使用2个非默认构造函数反序列化类

C# 使用2个非默认构造函数反序列化类,c#,json,C#,Json,我有一个类,它使用Json.net public class JsonSerializer { public string Serialize(object toSerialaze) { return JsonConvert.SerializeObject(toSerialaze); } public T Deserialize<T>(string toDeserialaze) { return JsonCon

我有一个类,它使用
Json.net

public class JsonSerializer
{
    public string Serialize(object toSerialaze)
    {
        return JsonConvert.SerializeObject(toSerialaze);
    }

    public T Deserialize<T>(string toDeserialaze)
    {
        return JsonConvert.DeserializeObject<T>(toDeserialaze);
    }
}
我得到以下例外情况:

其他信息:找不到用于type Library.Isbn的构造函数。一个类应该有一个默认构造函数、一个带参数的构造函数或一个标有JsonConstructor属性的构造函数。

我知道,我可以在反序列化时将
[JsonConstructor]
放在我需要使用的构造函数之前,但我不想让class
Isbn
知道Json。
我如何以另一种方式实现相同的行为?我如何让JsonConverter知道要使用两个构造函数中的哪一个?

一个选项是使用不同的类进行序列化。然后手动或使用AutoMapper映射到原始图像

作为奖励,您将发现您的业务对象可以自由地进行重构,而不必担心这会对序列化造成什么影响。因为你是对的,所以它不应该知道json

用静态方法替换公共构造函数

另一个选择是减少构造函数的数量,我尽量不超过一个,通常没有(我的意思是没有公共构造函数)

例如:

public Isbn(int groupCode, int publisherCode, int titleCode, int checkCode)
{
    _groupCode = groupCode;
    _publisherCode = publisherCode;
    _titleCode = titleCode;
    _checkCode = checkCode;
}

public static Isbn FromString(string isbn)
{
    if (isbn == null)
        throw new ArgumentNullException("isbn");
    if (isbn == "") return;
    if (!IsValid(isbn)) return;
    var isbnStrings = isbn.Split(new[] {'-', ' '}, StringSplitOptions.RemoveEmptyEntries);
    var groupCode = Convert.ToInt32(isbnStrings[0]);
    var publisherCode = Convert.ToInt32(isbnStrings[1]);
    var titleCode = Convert.ToInt32(isbnStrings[2]);
    var checkCode = Convert.ToInt32(isbnStrings[3]);
    return new Isbn(groupCode, publisherCode, titleCode, checkCode);
}

我认为这个答案有点晚了,但可能有人想用它

您可以通过创建自定义JsonConverter来实现这一点

public class IsbnConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof(Isbn);
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        if (reader.TokenType == JsonToken.StartObject)
        {
            var dict = new Dictionary<string, int>();
            serializer.Populate(reader, dict);
            return new Isbn(dict["groupCode"], dict["publisherCode"], dict["titleCode"], dict["checkCode"]);
        }

        if (reader.TokenType == JsonToken.String)
        {
            return new Isbn((string)reader.Value);
        }

        return null;
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
}
现在反序列化可以用于两种json

{ .... , isbn:{groupCode:1,publisherCode:2,titleCode:3,checkCode:4}, ...... }
{ .... , isbn:"1-2-3-4", .... }
例如:

public class Book
{
    public string Title { get; set; }
    public Isbn isbn { get; set; }
}

string json1 = @"{Title:""Title 1"", isbn:{groupCode:1,publisherCode:2,titleCode:3,checkCode:4}}";
string json2 = @"{Title:""Title 2"", isbn:""1-2-3-4""}";

var book1 = JsonConvert.DeserializeObject<Book>(json1, new IsbnConverter());
var book2 = JsonConvert.DeserializeObject<Book>(json2, new IsbnConverter());
公共课堂教材
{
公共字符串标题{get;set;}
公共Isbn Isbn{get;set;}
}
字符串json1=@“{Title:“Title 1”,isbn:{groupCode:1,publisherCode:2,titleCode:3,checkCode:4}”;
字符串json2=@“{Title:“Title 2”,isbn:“1-2-3-4”}”;
var book1=JsonConvert.DeserializeObject(json1,新的IsbnConverter());
var book2=JsonConvert.DeserializeObject(json2,新的IsbnConverter());

weston,谢谢你的回答!这是一个非常好的主意,不要有超过1个CJnstuctor!不客气,即使你想接受另一个答案,你也可以点击向上箭头为答案投票。如果你喜欢,请查看更多关于这种方法的论据,它基本上来自一本书《有效的Java》,其中大部分同样适用于C 35;“我认为这个答案有点晚了”嗯?询问后约一小时?另请参见:
{ .... , isbn:{groupCode:1,publisherCode:2,titleCode:3,checkCode:4}, ...... }
{ .... , isbn:"1-2-3-4", .... }
public class Book
{
    public string Title { get; set; }
    public Isbn isbn { get; set; }
}

string json1 = @"{Title:""Title 1"", isbn:{groupCode:1,publisherCode:2,titleCode:3,checkCode:4}}";
string json2 = @"{Title:""Title 2"", isbn:""1-2-3-4""}";

var book1 = JsonConvert.DeserializeObject<Book>(json1, new IsbnConverter());
var book2 = JsonConvert.DeserializeObject<Book>(json2, new IsbnConverter());