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: postmaster@xxxxx.ca \u2192 hamnifold@cxxxxxxxxems.com '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": "20180704185046.1.F263522F7F8571FE@mxxxxxx.ca"
},
{
"hap": "tempfailed",
"message": "Will retry in 14400 seconds: postmaster@xxxxxxxx.ca \u2192 conor@xxxxxxxxxy.org '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": "20180704225015.1.E917B878FC275EE7@mxxxxxxx.ca"
},
{
"hap": "opened",
"message": "Opened: jordan@lixxxxxxxxs.com",
"type": "info",
"created_at": "Thu, 05 Jul 2018 06:45:15 GMT",
"message_id": "20180704192612.1.856579D071F84CF8@xxxxxxx.ca"
},
{
"hap": "tempfailed",
"message": "Will retry in 14400 seconds: postmaster@mxxxxxxx.ca \u2192 ccrawford@xxxxxx.com '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": "20180704225014.1.33D047AC8A685236@xxxxxxxxi.ca"
},
//...
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:key-xxxxxxxxxxxxxxxxxxxxxxxxxxxx@api.mailgun.net/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);
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);
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");
//...
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.