1

I have an app that I would like to store some email setting in a json file.

The json file looks like:

{
"Id": 1,
"From": "myemail@whereever.com",
"Password": "mypassword",
"Port": 587,
"To": "myemail@whereever.com",
"SmtpAddress": "smtp.office365.com",
"TargetName": "STARTTLS/smtp.office365.com"
}

and C# code looks like :

public class EmailModel
{
    [JsonProperty(nameof(Id))]
    public int Id { get; set; }
    [JsonProperty(nameof(To))]
    public string To { get; set; }
    [JsonProperty(nameof(From))]
    public string From { get; set; }
    [JsonProperty(nameof(Port))]
    public int Port { get; set; }
    [JsonProperty(nameof(Password))]
    public string Password { get; set; }
    [JsonProperty(nameof(SmtpAddress))]
    public string SmtpAddress { get; set; }
    [JsonProperty(nameof(TargetName))]
    public string TargetName { get; set; }
}

and accessing it looks like:

public EmailModel EmailModel(int id)
{
    var filePath = AppDomain.CurrentDomain.BaseDirectory;

    using (var sr = new StreamReader(Path.Combine(filePath,"appsettings.json")))
    {
        string json = sr.ReadToEnd();
        return JsonConvert.DeserializeObject<EmailModel>(json);
    }
}

I have seen many posts for this, however none seem to work. I have added

var settings = new JsonSerializerSettings();
settings.MetadataPropertyHandling = MetadataPropertyHandling.Ignore;

in the EmailModel class and still all my values still end up null.

Update debugging through this I see that sr.ReadToEnd() returns:

 "{\r\n  \"EmailModel\": {\r\n    \"Id\": 1,\r\n    \"From\": \"myemail\",\r\n    \"Password\": \"myPassword\",\r\n    \"Port\": 587,\r\n    \"To\": \"myEmail\",\r\n    \"SmtpAddress\": \"smtp.office365.com\",\r\n    \"TargetName\": \"STARTTLS/smtp.office365.com\"\r\n  }\r\n}\r\n"

}

Update 2: I get a reply from appsetting.json and when I change code from

var filePath = AppDomain.CurrentDomain.BaseDirectory;
            var streamPath = Path.Combine(filePath, "appsettings.json");
            string json = null;
            using (var sr = new StreamReader(streamPath))
            {
                json = sr.ReadToEnd();

            }

to:

        var json = @"
            {
            ""Id"": 1,
            ""From"": ""myEmail"",
            ""Password"": ""myPassword"",
            ""Port"": 587,
            ""To"": ""myEmail"",
            ""SmtpAddress"": ""smtp.office365.com"",
            ""TargetName"": ""STARTTLS/smtp.office365.com""
            }";

my test doesnt fail.

JamTay317
  • 1,017
  • 3
  • 18
  • 37
  • 1
    Is the file path correct? Did it find the file? (so `File.Exists(streamReader'sFilePath)` returns `true`?) – aniski May 10 '16 at 10:36
  • 1
    If I modify that code to put the json in a string (rather than loading from file) and replace those `nameof` with static strings then it works fine. I'd check that the file is loading correctly as KAI suggests. In particular it might be worth verifying the value of json before you are calling the deserialize. You should only get null if there is no json object at all. If it existed even if none of the properties matched you should get an object back and not null. – Chris May 10 '16 at 10:43
  • 1
    If your properties will have the same name as the Json properties, why the JsonProperty attributes are set? – Gusman May 10 '16 at 10:46
  • changeing names do not work for me? – JamTay317 May 10 '16 at 12:20
  • If this is a file you write then read, how do you write the file? (it might be that what you are doing is not symmetric) – crashmstr May 10 '16 at 12:26

2 Answers2

3

Running your code proves, that there is no problem with the deserialization itself.

unless you are doing somethink else behind the scene. This works:

private static void EmailModel()
{
   var json = @"
              {
              ""Id"": 1,
              ""From"": ""myemail@whereever.com"",
              ""Password"": ""mypassword"",
              ""Port"": 587,
              ""To"": ""myemail@whereever.com"",
              ""SmtpAddress"": ""smtp.office365.com"",
              ""TargetName"": ""STARTTLS/smtp.office365.com""
              }";
  EmailModel result = null;
  var settings = new JsonSerializerSettings();
  settings.MetadataPropertyHandling = MetadataPropertyHandling.Ignore;

  result = JsonConvert.DeserializeObject<EmailModel>(json, settings);

  Console.WriteLine(result.From);
}

So as coments stated, try to check if your file exists and the given path is correct.

UPDATE:

After OP update, the situation changed, the JSON that is coming contains the root element (EmailModel), so it's cannot be serialized directly. This post contains deeper explanations.

Shortly, code need to be changed like this to work:

    private static void EmailModel()
    {
        var json = "{\r\n  \"EmailModel\": {\r\n    \"Id\": 1,\r\n    \"From\": \"myemail\",\r\n    \"Password\": \"myPassword\",\r\n    \"Port\": 587,\r\n    \"To\": \"myEmail\",\r\n    \"SmtpAddress\": \"smtp.office365.com\",\r\n    \"TargetName\": \"STARTTLS/smtp.office365.com\"\r\n  }\r\n}\r\n";

        JToken root = JObject.Parse(json);
        JToken model = root["EmailModel"];

        var result = JsonConvert.DeserializeObject<EmailModel>(model.ToString());

        Console.WriteLine(result.From);
    }
Community
  • 1
  • 1
3615
  • 3,787
  • 3
  • 20
  • 35
  • I am getting resuts back, but they dont look like this. they have the "{emailAddress:{...}}" can you help me parse this? – JamTay317 May 10 '16 at 11:38
  • Ok, so the next question if you can modify the response you are getting to escape the new line characters? Or you can't change the response format? – 3615 May 10 '16 at 11:53
  • Well, I dont know, My question is I am not still getting null values and but the json is returning values. also, your json that you simulated did work. – JamTay317 May 10 '16 at 11:57
  • Great! By the way, the solution @KIA suggested should theoretically be also a working one, but it implies additional wrapper class, that I've avoided. If your scendario is not performance critical, then I would keep the solution I've suggested. – 3615 May 10 '16 at 12:50
1

Your file contains corrupted data. Now it contains:

{
    EmailModel:
    {
        // ...
        // properties here
        // ...
    }
}

instead of

{
    // ...
    // properties here
    // ...
}

Update: If it does so, create a class:

public class EmailModelSerialize
{
    public EmailModel EmailModel { get; set; }
}

and serialize this way:

EmailModelSerialize model;
using (var sr = new StreamReader(Path.Combine(filePath, "appsettings.json")))
{
    string json = sr.ReadToEnd();
    model = JsonConvert.DeserializeObject<EmailModelSerialize>(json);
}
aniski
  • 1,263
  • 1
  • 16
  • 31
  • yes it contains EmailModel:{...} I have deleted appsetting.json and recreated it. not currupted. – JamTay317 May 10 '16 at 12:22
  • I've updated the answer, I meant it is corrupted for your serialization process. From the other view, the file is OK, but the serialization was "corrupted". :) – aniski May 10 '16 at 12:28