0

I have a JSON with the following content:

{"SMTP Host: ":"host","SMTP Port: ":"123","SMTP User Name: ":"ionut","SMTP User Password: ":"pass","SMTP From: ":"robert","SMTP Display Name: ":"aeg","d":"2022-05-25T11:24:06.459Z"}

What I want is to get the values of the JSON (host, 123, etc)in my app. What I have tried is:

    public class Root
        { 
            public string smtpHost { get; set; }
            public string smtpPort { get; set; }
            public string smtpUserName { get; set; }
            public string smtpPassword { get; set; }
            public string smtpFrommtpHost { get; set; }
            public string smtpDisplayName { get; set; }
        }
    
    public class CustomDocumentOperationService : DocumentOperationService
        {
         DocumentOperationResponse SendEmail(MailAddressCollection recipients, string subject, string messageBody, Attachment attachment)
            {
                using (StreamReader sr = new StreamReader(System.Web.HttpContext.Current.Server.MapPath("~/JSON/my-download.json")))
                {
                    List<Root> contentJSON = JsonConvert.DeserializeObject<List<Root>>(sr.ReadToEnd());
                    System.Diagnostics.Debug.WriteLine("***************************************contentJSON: " + contentJSON + "***************************************");
                }
    
/*I have tried also with the following 2line, but I get the error
'Unexpected character encountered while parsing value: C. Path '', line 0, position 0.'*/
                //Root friends = JsonConvert.DeserializeObject<Root>(System.Web.HttpContext.Current.Server.MapPath("~/JSON/my-download.json"));
                //System.Diagnostics.Debug.WriteLine("***************************************contentJSON: " + friends + "***************************************");

                //Here I want to get the values from JSON:
                string SmtpHost = "mail.test.com";
                int SmtpPort = 112;
                string SmtpUserName = "ionut@test.com";
                string SmtpUserPassword = "blablabla";
                string SmtpFrom = "ionut@test.com";
                string SmtpFromDisplayName = "Ionut";
             }
          }

Using this method, I get the following exception: Newtonsoft.Json.JsonSerializationException: 'Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.List1`. I know there's a topic about it, but it couldn't help solve the issue. What am I missing?

Ionut
  • 724
  • 2
  • 9
  • 25

1 Answers1

2

Your JSON contains a single object. You're trying to deserialize it as a list of objects. That would only be valid if it started with [ and ended with ].

Your commented out code tries to deserialize the right type, but using the result of MapPath instead of the actual JSON. I suggest you separate out the "loading the JSON" from the "deserializing the JSON":

string file = HttpContext.Current.Server.MapPath("~/JSON/my-download.json");
string json = File.ReadAllText(file);
Root root = JsonConvert.DeserializeObject<Root>(json);

I'd also strongly recommend renaming Root to a more meaningful name, e.g. ServerSettings or SmtpSettings - and rename the properties to be more conventional in .NET, using [JsonProperty] to specify the name in the JSON. For example, you could have:

public class SmtpSettings
{
    [JsonProperty("SMTP Host: ")]
    public string Host { get; set; }

    [JsonProperty("SMTP Port: ")]
    public string Port { get; set; }

    [JsonProperty("SMTP User Name: ")]
    public string UserName { get; set; }

    [JsonProperty("SMTP User Password: ")]
    public string UserPassword { get; set; }

    [JsonProperty("SMTP From: ")]
    public string FromAddress { get; set; }

    [JsonProperty("SMTP Display Name: ")]
    public string DisplayName { get; set; }
}

I would note that this is very weird JSON though, including spaces and colons in the property names. It would be rather more conventional as:

{
    "smtpHost": "...",
    "smtpPort": ...,
    "smtpUserName": "...",
    "smtpUserPassword": "...",
    "smtpFromAddress": "...",
    "smtpDisplayName": "..."
}

... ideally without the smtp prefix, admittedly... and with the port specified as a number rather than as a string. Including a plain-text password is "unfortunate" in terms of security, too.

Basically, if you can possibly change everything about this system, there's a lot that should be changed... but at least the above should get you started.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • Thank you for the reply! With your help, I don't get anymore the exception. My question now is how could I get the value from JSON? Instead of `string SmtpHost = "mail.test.com";` it should be something like `string SmtpHost = "json.value;` I know that the code is perfectible, but so far I want to get it working and then I will make the suggested updates. – Ionut May 27 '22 at 11:15
  • @Ionut: Um, you'd use `string host = root.smtpHost;`. (Or `string host = root.Host;` if you've changed the class definition as suggested.) It's just a property on the object you've deserialized... the fact that the data was populated from JSON is irrelevant, as it's just an object to use as any other. – Jon Skeet May 27 '22 at 11:22
  • Shouldn't be like `string SmtpHost = SmtpSettings.Host;`? – Ionut May 27 '22 at 11:33
  • @Ionut: No, because that would be accessing a *static* property. You're trying to access the property *of a specific object* (accessed via the variable you've declared and initialized). Note that if you followed normal .NET naming conventions, where local variables start with a lower case letter, that would help readability. – Jon Skeet May 27 '22 at 11:38