通过反序列化json文件在构造函数中初始化对象数据

时间:2016-11-17 14:16:45

标签: c# json object constructor

好的,所以我想摆脱第一个构造函数,并能够直接反序列化。有没有办法一次从json中拉出每个变量?或者是否有一个可以用来将它们全部拉出并填充对象的一揽子声明。

 public MasterEmailSettings()
 {
      _user = "";
      _password = "";
      _domain = "";
      _emailAddress = "";
 }
 public MasterEmailSettings(string path)
 {
      var tempObject = new MasterEmailSettings();

      try
      {
           tempObject = JsonConvert.DeserializeObject<MasterEmailSettings>(File.ReadAllText(path));
           _domain = tempObject.Domain;
           _password = tempObject.Password;
           _user = tempObject.User;
           _emailAddress = tempObject.EmailAddress;
      }
      catch (Exception ex)
      {
           Console.WriteLine(ex.ToString());
      }
 }

4 个答案:

答案 0 :(得分:1)

您无法在一个步骤中设置构造函数中的所有属性。

您可以将[JsonConstructor]与构造函数一起使用:Deserialize json into C# object for class which has default private constructor

答案 1 :(得分:1)

就个人而言,我不会创建一个构造函数来负责外出到磁盘,读取文件,使用第三方库反序列化到对象,然后只需要反序列化的一些内容。对象并放入类中的某些字段。通常,构造函数只传达对象初始化,而这反过来又将很多责任包含在我不确定你无论如何都需要做的构造函数中。

如果你真的想将这个逻辑封装到这个类的空间中,我有一个建议就是创建一个工厂方法。工厂方法更广泛地表明,为了初始化类型,还有实际工作要做:

public static MasterEmailSettings Create(string path){
    return JsonConvert.DeserializeObject<MasterEmailSettings>(File.ReadAllText(path))
}

我不完全确定原始构造函数的用例,其中代码将tempObject设置为对象的反序列化形式,只是为了设置几个字段?我们需要更多信息。

同样,你可能会更好地使用......

var emailSettings = JsonConvert.DeserializeObject<MasterEmailSettings>(File.ReadAllText(path)) 

...在您的代码中,只要您想要此功能,但如果您想要将其封装一下,上面的工厂方法将是一条很好的路径。

*更新* 我想在你想要从磁盘加载这些信息的时候读一下你不想尝试/捕获的评论,这是有意义的。上面的工厂方法+ try catch逻辑,你明确地捕获一个IOException将是一个很好的impl。

public static MasterEmailSettings Create(string path){
    try{
        return JsonConvert.DeserializeObject<MasterEmailSettings>(File.ReadAllText(path))
    }
    catch(IOException ex)
    {
        //Answer how the system should respond in the event that the file did not exist. Maybe you just want to log it and throw?
        throw; //Do not use throw ex as it will re-start the stack trace from the point the exception is thrown. Use either throw or throw new SomeException("", ex); to make sure the original stack trace on the exception is preserved.
    }
}

ReadAllText可以抛出一些其他异常,您可能需要考虑它们以及代码应如何响应它们:https://msdn.microsoft.com/en-us/library/ms143368(v=vs.110).aspx

答案 2 :(得分:1)

我把它分开一点点不同。我同意早先关于从对象中删除文件读取的答案,以及作为执行反序列化的静态方法

Command failed: C:\Program Files\Docker Toolbox\docker-machine.exe -D create -d virtualbox --virtualbox-memory 2048 default,Docker Machine Version: 0.8.2, build e18a919,Found binary path at C:\Program Files\Docker Toolbox\docker-machine.exe,Launching plugin server for driver virtualbox,Plugin server listening at address 127.0.0.1:53159,() Calling .GetVersion,Using API Version 1,() Calling .SetConfigRaw,() Calling .GetMachineName,(flag-lookup) Calling .GetMachineName,(flag-lookup) Calling .DriverName,(flag-lookup) Calling .GetCreateFlags,Found binary path at C:\Program Files\Docker Toolbox\docker-machine.exe,Launching plugin server for driver virtualbox,Plugin server listening at address 127.0.0.1:53163,() Calling .GetVersion,Using API Version 1,() Calling .SetConfigRaw,() Calling .GetMachineName,(default) Calling .GetMachineName,(default) Calling .DriverName, 

然后在您的代码中将其称为

public class MasterEmailSettings
{
    public string User { get; set; }
    public string Password { get; set; }
    public string Domain { get; set; }
    public string EmailAddress { get; set; }

    public static MasterEmailSettings Deserialize(string json)
    {
        return JsonConvert.DeserializeObject<MasterEmailSettings>(json);
    }
}

答案 3 :(得分:1)

你可以做这样的事情

public class MasterEmailSettings
{
    private static MasterEmailSettings _settings;
    public string User { get; }
    public string Domain { get; }
    public string Password { get; }
    public string EmailAddress { get; }

    private MasterEmailSettings()
    {
        this.User = "user";
        this.Password = "pw";
        this.Domain = "domain";
        this.EmailAddress = "foo@bar.com";
    }

    public static MasterEmailSettings Load(string path)
    {
        if (!File.Exists(path))
        {
            _settings = new MasterEmailSettings();
            Save(path);
            return _settings;
        }

        var json = File.ReadAllText(path);
        _settings = JsonConvert.DeserializeObject<MasterEmailSettings>(File.ReadAllText(path));
        return _settings;
    }

    private static void Save(string path)
    {
        var json = JsonConvert.SerializeObject(_settings, Formatting.Indented);
        File.WriteAllText(path, json);
    }
}

然后就这样称呼它

var settings = MasterEmailSettings.Load("yourpath");