2

Getting an error saying

JsonReaderException: Unexpected character encountered while parsing value: M. Path ', line 0, position 0.

when try to parse JSON response (not entire, but first few items, I changed in the xxxxxx's for anonymity):

{
 "total_count": 1091,
 "items": [
 {
 "hap": "retry_limit_reached",
 "message": "Retry limit reached. Dropped: [email protected] \u2192 [email protected] 'REMINDER - Pattison Stampede BBQ (Jul 11, 2018)' No MX for crscranessystems.com Server response: 498 No MX for crscranessystems.com",
 "type": "error",
 "created_at": "Thu, 05 Jul 2018 06:45:48 GMT",
 "message_id": "[email protected]"
 },
 {
 "hap": "tempfailed",
 "message": "Will retry in 14400 seconds: [email protected] \u2192 [email protected] 'REMINDER - Pattison Stampede BBQ (Jul 11, 2018)' No MX for greexxxxxxxy.org Server response: 498 No MX for grexxxxxxy.org",
 "type": "warn",
 "created_at": "Thu, 05 Jul 2018 06:45:17 GMT",
 "message_id": "[email protected]"
 },
 {
 "hap": "opened",
 "message": "Opened: [email protected]",
 "type": "info",
 "created_at": "Thu, 05 Jul 2018 06:45:15 GMT",
 "message_id": "[email protected]"
 },
 {
 "hap": "tempfailed",
 "message": "Will retry in 14400 seconds: [email protected] \u2192 [email protected] 'SUBJECT' No MX for step-eps.com Server response: 498 No MX for stxxxxxx.com",
 "type": "warn",
 "created_at": "Thu, 05 Jul 2018 06:45:14 GMT",
 "message_id": "[email protected]"
 },
 //...

Here is part of my code:

if(response.IsSuccessStatusCode)
{
 ViewBag.Msg = "Success";
 var stresult = await response.Content.ReadAsStringAsync(); 
 var flogs = JsonConvert.DeserializeObject<List<EmailLog>>(stresult);
 logs = flogs.ToList();
}

Here is the emaillog model:

public class EmailLog
{
 public string hap { get; set; }
 public string message { get; set; }
 public string type { get; set; }
 public string created_at { get; set; }
 public string message_id { get; set; }
}

This is the first time I have ever used RESTful API and JSON, so I might be missing something easy.

EDIT:

This is my full controller code which makes the API request:

HttpClient client = new HttpClient();
 client.BaseAddress = new Uri("https://api:[email protected]/v3");
 List<EmailLog> logs = new List<EmailLog>();
 HttpResponseMessage response = await client.GetAsync("/mg.xxxxx.ca/log");
 if (response.IsSuccessStatusCode)
 {
 // var stresult = await response.Content.ReadAsStringAsync(); 
 // var flogs = JsonConvert.DeserializeObject<List<EmailLog>>(stresult);
 // logs = flogs.ToList();
 var json = await response.Content.ReadAsStringAsync();
 var jObject = JObject.Parse(json);
 if (jObject.ContainsKey("items"))
 {
 ViewBag.Msg = "Success";
 logs = jObject["items"].ToObject<List<EmailLog>>();
 }
 //var logs = JsonConvert.DeserializeObject<ApiResponse>(json);
 }
 else { ViewBag.Msg = "Fail"; }
 return View(logs);
asked Jul 5, 2018 at 7:09
0

2 Answers 2

2

The problem is trying to get a list of EmailLog objects directly because they are enclosed within the "items" element of your json response.

You can solve it by using a wrapper class, for example:

public class ApiResponse
{
 [JsonProperty(PropertyName = "total_count")]
 public int TotalCount { get; set; }
 [JsonProperty(PropertyName = "items")]
 public List<EmailLog> Items { get; set; }
}

And then you don't need to use a list to deserialize:

var flogs = JsonConvert.DeserializeObject<ApiResponse>(json);
answered Jul 5, 2018 at 8:50
Sign up to request clarification or add additional context in comments.

Comments

1

Here is an alternative to creating a root object as already explained in another answer

This approach takes advantage of the Linq To JSON provided by the Json.Net, which is being used to deserialize the JSON.

if(response.IsSuccessStatusCode) {
 ViewBag.Msg = "Success";
 var json = await response.Content.ReadAsStringAsync();
 var jObject = JObject.Parse(json);
 if (jObject.ContainsKey("items"))
 logs = jObject["items"].ToObject<List<EmailLog>>(); 
}

The JSON is parsed and only the desired key is extracted.

This assumes that value of "total_count" was not needed so only extracts the items value.

If the entire object is wanted then defining a root object and deserializing to that would be the easier approach, as demonstrated in @Isma's answer

UPDATE:

Based on discussion you indicated that the service is currently returning

"Mailgun Magnificent API"

which would match the invalid character exception being thrown trying to parse M, as it is clearly not well formatted JSON.

After reviewing the Mailgun documentation it looks like the URL you are using will only work in a browser and was not meant to be used the HttpClient class.

The documentation explains that the request should be made using BASIC authorization

For example.

var myMailgunDomain = "https://api.mailgun.net/v3/mg.xxxxx.ca/"; 
var client = new HttpClient() {
 BaseAddress = new Uri(myMailgunDomain)
};
var apiKey = "api:key-xxxxxxxxxxxxxxxxxxxxxxxxxxxx";
var parameter = Convert.ToBase64String(Encoding.ASCII.GetBytes(apiKey));
client.DefaultRequestHeaders
 .Authorization = new AuthenticationHeaderValue("Basic", parameter);
HttpResponseMessage response = await client.GetAsync("log");
//...
answered Jul 5, 2018 at 9:49

11 Comments

This answer was more correct for my situation, thank you
Still getting same error message, going to try the other solution
@dave317 recheck the JSON string being returned, looking over the exception message it appears the string is starting with an invalid charater at the start of the string (position 0), which would make the string invalid JSON, hence the error. Confirm that the JSON being returned is valid JSON.
How would I check that? If I enter my Uri and Query in a Browser it brings up the JSON I pasted into my question above..
@dave317 can you show more of the code that is making the request for the data? I assume you are using a HttpClient and that response is a HttpResponseMessage
|

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.