Encountered unexpected character ‘<’” error serializing in DataContractJsonSerializer.ReadObject(stream) - c#

we're sending HTTP request to Bing maps with address details to get back the address map point. The response of the HTTP request is read as stream async, this stream is then deserialized to Bing response format. When I deserialize, I'm getting this error: System.Runtime.Serialization.SerializationException : Error while deserializing the object of type Previseo.Workflows.BingResponse. Unexpected character '<'.
Your help is so appreciated.
I've used Fiddler to see the response of bings which sends it back in the form of JSON:https://i.stack.imgur.com/LPIeW.png
JSON returned as text:
{"authenticationResultCode":"ValidCredentials","brandLogoUri":"http:\/\/dev.virtualearth.net\/Branding\/logo_powered_by.png","copyright":"Copyright © 2019 Microsoft and its suppliers. All rights reserved. This API cannot be accessed and the content and any results may not be used, reproduced or transmitted in any manner without express written permission from Microsoft Corporation.","resourceSets":[{"estimatedTotal":1,"resources":[{"__type":"Location:http:\/\/schemas.microsoft.com\/search\/local\/ws\/rest\/v1","bbox":[46.175388336181641,5.1528801918029785,46.231620788574219,5.28734016418457],"name":"01000, Ain, France","point":{"type":"Point","coordinates":[46.203506469726563,5.2217612266540527]},"address":{"adminDistrict":"Auvergne-Rhone-Alpes","adminDistrict2":"Ain","countryRegion":"France","formattedAddress":"01000, Ain, France","locality":"Bourg-en-Bresse","postalCode":"01000"},"confidence":"High","entityType":"Postcode1","geocodePoints":[{"type":"Point","coordinates":[46.203506469726563,5.2217612266540527],"calculationMethod":"Rooftop","usageTypes":["Display"]}],"matchCodes":["Good"]}]}],"statusCode":200,"statusDescription":"OK","traceId":"e1464a431e5e46b9854053ed8ae76ba8|DU00000D78|7.7.0.0|Ref A: 865592F3CBB74AD6ADA8A71D8344F297 Ref B: DB3EDGE0817 Ref C: 2019-08-07T07:56:20Z"}
private MapPoint GetAddressMapPoint(string address, string ville)
{
int idx;
string postal, city, url;
HttpClient client;
HttpResponseMessage apires;
DataContractJsonSerializer jsonSerializer;
BingResponse bingResp = null;
idx = ville.IndexOf(" ");
postal = ville.Substring(0, idx);
city = ville.Substring(idx + 1);
url = BING_MAPS_BASE_ADDRESS + $"REST/v1/Locations/FR/{postal}/{city}/{address.Trim()}?key={BingMapsKey}";
client = new HttpClient();
apires = client.GetAsync(url).Result;
jsonSerializer = new DataContractJsonSerializer(typeof(BingResponse));
Stream stream = apires.Content.ReadAsStreamAsync().Result;
bingResp = (BingResponse)jsonSerializer.ReadObject(stream); //here is where I'm getting the error 'Unexpected caracter '<'
if (bingResp.resourceSets.Count > 0)
{
if (bingResp.resourceSets[0].resources.Count > 0)
{
var point = bingResp.resourceSets[0].resources[0].point;
return point;
}
}
return null;
}
public class BingResponse
{
[DataMember]
public string authenticationResultCode { get; set; }
[DataMember]
public string brandLogoUri { get; set; }
[DataMember]
public string copyright { get; set; }
[DataMember]
public List<ResourceSet> resourceSets { get; set; }
[DataMember]
public int statusCode { get; set; }
[DataMember]
public string statusDescription { get; set; }
[DataMember]
public string traceId { get; set; }
}

Related

SendGrid: Deserialization of Email Activity API JSON Response Not Populating Objects

I am calling SendGrid's Email Activity API using the RestSharp RestClient and it is properly returning data via a standard JSON response.
However, I'd like to deserialize that into a C# object since it would be much easier to work with than a raw JSON string. So I created a C# class that has public properties for each field in the JSON response, and gave them annotations with the exact name of the JSON fields.
But when I call JsonDeserializer().Deserialize>(response), while there's no error/exception, all of the fields in the objects are NULL.
Any ideas what's wrong? (You can just take out the "EventType" references as it's not really relevant here). Relevant code is below.
I'm using RestSharp v106.6.10.0 and Newtonsoft.Json v9.0.0.0 (the latter probably older but that's the library we normally use).
Project is .NET v4.6.1
private void QuerySendGridForEmailActivity(EventType eventType)
{
string query = string.Empty;
RestClient client = null;//new RestClient(emailActivityEndpoint);
RestRequest request = new RestRequest(Method.GET);
request.AddHeader("Authorization", "Bearer " + apiKey);
request.AddParameter("limit", "1000");
if (eventType == EventType.Opens)
{
// request.AddParameter("query", WebUtility.UrlEncode("(Contains(events,\"open\"))"));
client = new RestClient(emailActivityEndpoint + "?limit=10&query=" + System.Web.HttpUtility.UrlPathEncode("(Contains(events,\"open\"))"));
}
IRestResponse response = client.Execute(request);
if (response != null && response.StatusCode == HttpStatusCode.OK)
{
this.emailActivityEvents = new JsonDeserializer().Deserialize<List<EmailActivityEvent>>(response);
int i = 0;
}
else
{
}
}
public class EmailActivityEvent
{
[DeserializeAs(Name = "from_email")]
public string FromEmail { get;set; }
[DeserializeAs(Name = "msg_id")]
public string MessageId { get; set; }
[DeserializeAs(Name = "subject")]
public string Subject { get; set; }
[DeserializeAs(Name = "to_email")]
public string ToEmail { get; set; }
[DeserializeAs(Name = "status")]
public string Status { get; set; }
[DeserializeAs(Name = "opens_count")]
public int OpensCount { get; set; }
[DeserializeAs(Name = "clicks_count")]
public int ClicksCount { get; set; }
[DeserializeAs(Name = "last_event_time")]
public DateTime LastEventTime { get; set; }
}
Ok, I should've gotten this earlier but I didn't think I needed to do this.
I had to add another class that I named "EmailActivity" that just has a List<> of the email events, with a deserialize annotation matching the actual name of the item in JSON. Like this:
public class EmailActivity
{
[DeserializeAs(Name = "messages")]
public List<EmailActivityEvent> Events { get; set; }
}
Then just adjust the deserialize call slightly to this:
var emailActivity = new JsonDeserializer().Deserialize<EmailActivity>(response);
And that did it. Duh.
Just FYI, the JSON being returned was in this format:
{"messages":
[{
"from_email":"from#email.com",
"msg_id":"msgid",
"subject":"Test",
"to_email":"to#email.com",
"status":"delivered",
"opens_count":0,
"clicks_count":0,
"last_event_time":"2019-11-26T20:30:02Z"
},
{
"from_email":"from#email.com",
"msg_id":"msgid",
"subject":"Test",
"to_email":"to#email.com",
"status":"delivered",
"opens_count":0,
"clicks_count":0,
"last_event_time":"2019-11-26T20:30:01Z"
},
{
"from_email":"from#email.com",
"msg_id":"msgid",
"subject":"Test",
"to_email":"to#email.com",
"status":"delivered",
"opens_count":0,
"clicks_count":0,
"last_event_time":"2019-11-25T22:06:25Z"
}
]}
Thanks for your comments!

The header of response web service in c#

The format of response
adbc91a43e988a3b5b745b8529a90b61
<RESPONSE Stamp="YYYY-MM-DDTHH:MM:SSZ" RE="…" ERR_TEXT="…">
<PaymentID>3242343</PaymentID>
</RESPONSE>
The first line of the response consists of a md5-hash xml-response + parameters hash, followed by
xml-response.
The main element of xml-response is called RESPONSE...
How and where to add the hash code?
Thanks
I have XML without hashcode. My code in c#
[WebMethod]
public RESPONSE GET( string id)
{
RESPONSE res = new RESPONSE();
res.ERR_TEXT = "";
res.RE = "";
res.Stamp = DateTime.Now.ToString("yyyy-MM-ddthh-mm-ssz");
res.PaymentID = id;
return res;
}
public class RESPONSE
{
[XmlAttribute]
public string ERR_TEXT { get; set; }
[XmlAttribute]
public string RE { get; set; }
[XmlAttribute]
public string Stamp { get; set; }
public string PaymentID { get; set; }
}
In output get only XML. But must still pass the hash code.
I must send a response to a client request. And they want that at response body was hash and xml. And how it should look like I can not understand.

Facebook get friends JSON response is invalid

I am developing an app for iOS using Xamarin Studio (C#) in Mac OS X. I want to get a list of the user's friends on Facebook, so I added Facebook's component from Xamarin's component store and made a request(code at the bottom). This is the response I get:
{
data = (
{
"first_name" = Dev;
id = 100001438778777;
"last_name" = Accu;
}
);
paging = {
next = "https://graph.facebook.com/v2.0/100005203000814/friends?fields=id,first_name,last_name&format=json&access_token=CAAK3hGOIm2ABANPUcr2QU1t8gqLNsZCJBrc8ZCZCqUSwHkX2f43VHarvc1ZABbjDrY7jIO0OT5ZBRBiZC1audQnIvxCsOu60y30iR84jVa56beNTptixj7AFqT92ZBGdyxDshFHHxkFDgCg9JyRZBYfqaGKkeJkuxJVUXDq8eR8ZCmRlslpOVSavQZC1hCcxOwdgFS2jWQdGZBFVSYTkrhkavfP&limit=5000&offset=5000&__after_id=enc_Aey-LjP59ZnmKMcZKcEr94tTUPIHIvWj9JnMwkIVSvxJ9RBYBqhBt3bGKlURY4SHBCDeH8BM_wSsqICzEFgKiZvh";
};
}
There is 2 problems with this response, it only includes 1 friend for some unknown reason, and the JSON is not valid, so ultimately parsing this fails. The following is the code I use to make the request:
var friendsRequest = await new FBRequest(FBSession.ActiveSession, "/me/friends?fields=id,first_name,last_name").StartAsync();
var friendsArray = friendsRequest.Result as MonoTouch.Foundation.NSMutableDictionary;
var response = FriendResponse.FromJson(friendsArray.ToString());
List<FacebookProfile> friends = new List<FacebookProfile>();
foreach (var friend in response.Data)
{
friends.Add(new FacebookProfile(friend.ID, friend.FirstName, friend.LastName));
}
And here is the parsing classes:
public class NextPage
{
public string Next { get; set; }
}
public class Friend
{
public string ID { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
public class FriendResponse
{
public List<Friend> Data { get; set; }
public NextPage Paging { get; set; }
public static FriendResponse FromJson(string json)
{
JsConfig.EmitLowercaseUnderscoreNames = true;
return JsonSerializer.DeserializeFromString<FriendResponse>(json);
}
}
The component is a 1:1 binding to the objective-c SDK. The response that Facebook returns is an NSDictionary underneath, and if you run ToString() on it, it will return the string representation of the NSDictionary which is totally different from a JSON
string. What you have to do is serialize that NSDictionary object back into a JSON string. Here is an example of how to do this:
var friendsRequest = await new FBRequest(FBSession.ActiveSession, "/me/friends?fields=id,first_name,last_name").StartAsync();
// Convert back the object into a Json
NSError error;
var jsonData = NSJsonSerialization.Serialize (friendsRequest.Result, 0, out error);
var jsonString = (string) NSString.FromData (jsonData, NSStringEncoding.UTF8);
var response = FriendResponse.FromJson(jsonString);
"jsonString" will have the correct JSON string data representation this time.
Courtesy of Alex DeSoto. =)

Metro App - deserialize JSON String

I'd like to deserialize a JSON string which I get from a webservice. My problem is, that the deserialized object class array (of type Result) has always 0 items in it....
But the webservice returns the correct string.
So I think the failure occurs in the way how I deserialize the string/stream.
Any ideas what's my fault?
//JSON result string:
{"Results":
[{"Result":{
"Name":"Rechnung2",
"Date1":"2012-10-05",
"Item1":"50",
"Item2":"10",
"CompanyName":"Contoso",
"Description":"My description"}}]
}
[DataContract]
public class Result
{
[DataMember]
public string Name { get; set; }
[DataMember]
public string Date1 { get; set; }
[DataMember]
public string Item1 { get; set; }
[DataMember]
public string Item2 { get; set; }
[DataMember]
public string CompanyName { get; set; }
[DataMember]
public string Description { get; set; }
}
public async void GetjsonStream()
{
HttpClient client = new HttpClient();
string url = "http://localhost/test/api.php?format=json&key=12345";
HttpResponseMessage response = await client.GetAsync(url);
//ReadAsStringAsync() works fine, so I think ReadAsStreamAsync() works also fine
var str = await response.Content.ReadAsStreamAsync();
DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(Result[]));
//Result has always 0 items
Result[] res = (Result[])ser.ReadObject(str);
}
I haven't used DataContractJsonSerializer myself, so this may not be the best approach - but I suspect that the problem is that the JSON represents "an object containing a collection of results" - not "a collection of results".
Try this, in addition to your existing code:
[DataContract]
public class ResultCollection
{
[DataMember]
public Result[] Results { get; set; }
}
...
var ser = new DataContractJsonSerializer(typeof(ResultCollection));
var collection = (ResultCollection)ser.ReadObject(str);
var results = collection.Results;
You may be able to change the type of Results to List<Result> too, if that's helpful.
(I've just tried the code above, and it gave me the right result, so it looks like this is at least along the right lines...)

I can't decrypt text

I have url http://translate.google.ru/translate_a/t?client=x&text=ввійти вийти&sl=ua&tl=en
If you will go through this link in response you will have js file with normal translate text:
{"sentences":[{"trans":"enter exit","orig":"ввійти вийти","translit":"","src_translit":"vviy̆ty vyy̆ty"}],"src":"uk","server_time":127}
But if you get this data through program you will have encrypt translate data:
{"sentences":[{"trans":"\u00D0 \u00B2 \u00D0 \u00B2 \u00D1-\u00D0 \u00B9 \u00D1,
\u00D0 \u00B8 \u00D0 \u00B2 \u00D0 \u00B8 \u00D0 \u00B9 \u00D1, \u00D0 \u00B8",
"orig":"\u00D0\u00B2\u00D0\u00B2\u00D1?\u00D0\u00B9\u00D1?\u00D0\u00B8 \u00D0\u0
0B2\u00D0\u00B8\u00D0\u00B9\u00D1?\u00D0\u00B8","translit":"","src_translit":""}
],"src":"is","server_time":4}
Through this code i got this data.
string url = #"http://translate.google.ru/translate_a/t?client=x&text=ввійти вийти&sl=ua&tl=en";
WebRequest request = WebRequest.Create(url);
request.Timeout = 5000;
WebResponse responce = request.GetResponse();
Stream stream = responce.GetResponseStream();
StreamReader st = new StreamReader(stream);
string responsText = st.ReadToEnd();
Console.WriteLine(responsText);
Console.ReadLine();
How can i decrypt this data?
The data is not encrypted. It is encoded. If you use proper JSON deserialization, like the DataJsonContractSerializer class, this will not be a problem, because the framework will decode the data for you.
[DataContract]
public class TranslationData {
[DataMember(Name = "sentences")]
public Sentence[] Sentences { get; set; }
[DataMember(Name = "src")]
public string Source { get; set; }
[DataMember(Name = "server_time")]
public int ServerTime { get; set; }
}
[DataContract]
public class Sentence {
[DataMember(Name = "trans")]
public string Translation { get; set; }
[DataMember(Name = "orig")]
public string Original { get; set; }
[DataMember(Name = "translit")]
public string Transliteration { get; set; }
[DataMember(Name = "src_translit")]
public string SourceTransliteration { get; set; }
}
Then use the System.Runtime.Serialization.Json.DataContractJsonSerializer class for deserialization (you have to add a reference to the System.Runtime.Serialization assembly) to read from the response stream directly:
var serializer = new DataContractJsonSerializer(typeof(TranslationData));
return (TranslationData)serializer.ReadObject(theResponseStream);
There are other ways of doing this, but this way you'll get nice typed data.

Categories