Windows App - Using XML in textbox - c#

[DataContract]
public class RootObject
{
[DataMember]
public int RecipeID { get; set; }
[DataMember]
public string Title { get; set; }
[DataMember]
public string Description { get; set; }
[DataMember]
public string Cuisine { get; set; }
[DataMember]
public string Category { get; set; }
[DataMember]
}
public async static Task<RootObject> GetRecipe()
{
var http = new HttpClient();
var url = String.Format("http://api.bigoven.com/recipe/196149?api_key=//apikey");
var response = await http.GetAsync(url);
var result = await response.Content.ReadAsStringAsync();
XmlSerializer serializer = new XmlSerializer(typeof(RootObject));
var ms = new MemoryStream(Encoding.UTF8.GetBytes(result));
XmlReader reader = XmlReader.Create(ms);
RootObject i;
i = (RootObject)serializer.Deserialize(reader);
return i;
}
I use the above method in a bigoven class which gets the data of a recipe as XML data such as:
<Recipe xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<RecipeID>196149</RecipeID>
<Title>Lasagna</Title>
<Cuisine>Italian</Cuisine>
and I would like to put the data for the title and cuisine into textboxes, however when I try the method below I get the error "Recipe xmlns='' was not expected."
RootObject myRecipe = await bigoven.GetRecipe();
textBox.Text = myRecipe.Title;

Answered before. Basically this:
When serialising an XML document to a .NET string, the encoding must be set to UTF-16. Strings are stored as UTF-16 internally, so this is the only encoding that makes sense. If you want to store data in a different encoding, you use a byte array instead.
See the entire thread here:
Using StringWriter for XML Serialization

It looks like your Json serializer might be trying to deserialize xml data.
You might try looking at the raw string in result and making sure that it's actually JSON data. If it's not, you need to find the appropriate deserailizer to use.
I'm guessing result contains XML in which case you'd need to use an XML Deserializer to convert it to a RootObject
Here's the link for the .NET one:
https://msdn.microsoft.com/en-us/library/tz8csy73(v=vs.110).aspx

Related

How do I parse JSON data which contains only arrays and nested arrays with no property names?

So I've looked around for tutorials on this and all the tutorials I've found doesn't have JSON that looks like the one I'm trying to parse.
I'm trying to parse JSON from this website https://www.steamcardexchange.net/api/request.php?GetBadgePrices_Guest
Since it doesn't have any identifiers for each thing like name, id etc I'm not sure how I will go about extracting data from it.
My only interest is really getting the first number of each item
[["449940","! That Bastard Is Trying To Steal Our Gold !"],5,"$0.64","1519294200"]
so what I want to extract from this item would be "449940".
This is what I've got so far
using (var client = new WebClient())
{
client.DownloadFile("https://www.steamcardexchange.net/api/request.php?GetBadgePrices_Guest", "data.json");
}
using (StreamReader r = new StreamReader("data.json"))
{
string json = r.ReadToEnd();
//Parse somehow
}
Any tips?
I took this up out of sheer curiosity because I had no idea how to parse this either. Perhaps there's a much better way.
I started by pasting a fragment of this into json2csharp.com.
The class it generates is
public class RootObject
{
public List<List<object>> data { get; set; }
}
From there I wrote some classes that correspond to what I think the data is supposed to look like. The names of the classes and properties are meaningless, so change them to whatever these actually represent.
public class OutputItem
{
public Message Message { get; set; }
public long Int64Value { get; set; } // 5
public string StringThatLooksLikeCurrency { get; set; } // "$0.64"
public string StringThatLooksNumeric { get; set; } // "1519294200"
}
public class Message
{
public string MessageId { get; set; } // "449940"
public string MessageText { get; set; } // "! That Dude..."
}
And finally, some sample code that takes a fragment of that JSON and converts it to a list of OutputItem. In order to figure this out I first deserialized the JSON to RootObject, then I inspected the deserialized object in the debugger to make sense of what it looked like.
var json = #"{ ""data"": [[[ ""449940"", ""! That Dude Is Trying To Steal Our Gold !"" ], 5, ""$0.64"", ""1519294200"" ], [[ ""303720"", ""#killallzombies"" ], 5, ""$0.56"", ""1519322799"" ]]}";
var parsed = JsonConvert.DeserializeObject<RootObject>(json);
var outputItems = new List<OutputItem>();
foreach (var listOfObject in parsed.data)
{
var outputItem = new OutputItem();
var message = (JArray) listOfObject[0];
outputItem.Message = new Message {MessageId = (string) message[0],
MessageText = (string) message[1]};
outputItem.Int64Value = (long) listOfObject[1];
outputItem.StringThatLooksLikeCurrency = (string) listOfObject[2];
outputItem.StringThatLooksNumeric = (string) listOfObject[3];
outputItems.Add(outputItem);
}

WCF Deserialize JSON String

I had edited my question :
How can i deserialize the JSON string shows below :
"{\"acctId\": \"Test10001\",\"amount\": 200,\"currency\": \"USD\",\"Code\": \"Test\",\"serialNo\": \"1234566789asdsad0\"}"
Please give suggestion how can I get the data by using this method or any other recommended method.
Suggesting you to use StreamWriter as below.
Use this function and pass your string and return a the Stream which will give you the desired JSON Content
public static Stream GenerateStreamFromString(string s)
{
MemoryStream stream = new MemoryStream();
StreamWriter writer = new StreamWriter(stream);
writer.Write(s);
writer.Flush();
stream.Position = 0;
return stream;
}
The payload of your POST request seems to be in JSON format, so you should use a JSON parsing library to parse it, such as Json.NET. Then you would write something like:
JsonConvert.DeserializeObject<YourRequestObject>(res)
I think below code should serve your purpose:
public class DeserializedData
{
public string acctId { get; set; }
public string amount { get; set; }
public string currency { get; set; }
public string Code { get; set; }
public string serialNo { get; set; }
}
StreamReader reader = new StreamReader(streamdata);
string res = reader.ReadToEnd();
Use third party dlls like Json.NET or Restsharp:
1.) Using Json.Net Json.NET
var result = JsonConvert.DeserializeObject<DeserializedData>(res);
2.) Using Restsharp Restsharp
var jsonDeserializer = new RestSharp.Deserializers.JsonDeserializer();
var response = jsonDeserializer.Deserialize<DeserializedData>(res);
Let me know if it doesn't work for you.
you can read Json string like this
dynamic stuff = JObject.Parse(res.ToString());
string acctId= stuff.acctId;
But the response string you are parsing should be json formatted.

C# GET REST xml to object deserialization encoding clash

I wanna get xml file from http and convert it to object.
So right now I have 2 methods: one to get http response body like that:
var httpClient = new HttpClient();
var op = httpClient.GetStringAsync(uri);
var httpResponseBody = "";
try {
var httpResponse = await httpClient.GetAsync(uri);
httpResponse.EnsureSuccessStatusCode();
httpResponseBody = await httpResponse.Content.ReadAsStringAsync();
return httpResponseBody;
}
...
which returns string httpResponseBody.
Second one tries to convert this xml in string to object:
res = await task;
var reader = new XmlSerializer(typeof(Schedule));
using (var tr = new MemoryStream(Encoding.UTF8.GetBytes(res)))
{
var schedule = (Schedule)reader.Deserialize(tr);
return schedule;
}
The problem is that the content I receive is in different encoding and I don't know how to convert it to make deserialization possible.
I am getting something like this:
<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<ramowka><dzien name=\"PoniedziaÅ\u0082ek\" count=\"2\"/></ramowka>\n
How to get rid of '\n' and Å\u0082 (should be ł) ?
Right now I am getting Exception from reader.Deserialize: {"<ramowka xmlns=''> was not expected."}
Schedule class:
[XmlType(AnonymousType = true)]
[XmlRootAttribute(Namespace = "", IsNullable = false)]
public class Schedule
{
[XmlElementAttribute("ramowka")]
public ScheduleDay[] AuditionDays { get; set; }
}
I've changed Schedule class to:
[XmlType(AnonymousType = true)]
[XmlRootAttribute("ramowka")]
public class Schedule
{
[XmlElementAttribute("dzien")]
public ScheduleDay[] AuditionDays { get; set; }
}
Now it looks like working. Thanks Petter for hint with Root attribute.
Setting the root object on the XmlSerializer fixes the problem:
var reader = new XmlSerializer(typeof(Schedule), new XmlRootAttribute("ramowka"));
...though I used slightly different attributes:
[DataContract]
public class ScheduleDay
{
[DataMember, XmlAttribute]
public string name { get; set; }
[DataMember, XmlAttribute]
public string count { get; set; }
}
[DataContract]
public class Schedule
{
[DataMember]
public ScheduleDay dzien { get; set; }
}
I haven't tried yours yet, but these work.
For a collection of ScheduleDays, this combo works:
[XmlType("dzien")]
public class ScheduleDay
{
[XmlAttribute]
public string name { get; set; }
[XmlAttribute]
public string count { get; set; }
}
Usage:
XmlSerializer reader = new XmlSerializer(typeof(List<ScheduleDay>), new XmlRootAttribute("ramowka"));
using (MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(Xml)))
{
List<ScheduleDay> schedule = (List<ScheduleDay>)reader.Deserialize(stream);
}
The Schedule class just disappeared from the equation.
Escapes in the HTML
The \ns are part of the XML structure, so no need to worry about those. The deserializer will translate \u0082 into its equivalent character, which is
BREAK PERMITTED HERE. Which you probably don't want. The Å looks out of place too -- it's the last letter of the Norwegian alphabet and not used in Polish, AFAIK.

DataContractJsonSerializer exception

I am getting this error when using my class.
Error
Expecting element 'root' from namespace ''.. Encountered 'None' with
name '', namespace
My Class
[DataContract]
public class EntryData
{
[DataMember]
public string EntryId { get; set; }
[DataMember]
public string EmailAddress { get; set; }
[DataMember]
public string StatusCode { get; set; }
[DataMember]
public string TotalVoteCount { get; set; }
public static T Deserialise<T>(string json)
{
var obj = Activator.CreateInstance<T>();
using (var memoryStream = new MemoryStream(Encoding.Unicode.GetBytes(json)))
{
memoryStream.Position = 0;
var serializer = new DataContractJsonSerializer(obj.GetType());
obj = (T)serializer.ReadObject(memoryStream); // getting exception here
return obj;
}
}
}
USAGE
string responseJson = new StreamReader(HttpContext.Current.Request.InputStream).ReadToEnd();
var results = EntryData.Deserialise<EntryData>(response)
I have seen online that it has to do with the memoryStream position BUT as you can see i am setting it to the beginning.
Please help.
Json going to handler
I don't set StatusCode or TotalVoteCount when passing JSON in. I don't think this is the problem though.
{
"EntryId":"43",
"EmailAddress":"test#email.com"
}
ANSWER
Instead of using Deserialize method in my class I am using now this.
//commented out this code.
string responseJson = new StreamReader(HttpContext.Current.Request.InputStream).ReadToEnd();
var results = EntryData.Deserialise<EntryData>(response)
// this is the way to go using JavaScriptSerializer
var serializer = new JavaScriptSerializer();
var results = serializer.Deserialize<EntryData>(response);
Could it be caused by your JSON names not matching your property names in C#?
My understanding is that
{
"FirstName" : "Mark"
}
Would be able to deserialize into:
[DataContract]
public class Person
{
[DataMember]
public string FirstName {get; set;}
}
but this wouldn't be able to serialize
{
"Name" : "Mark"
}
unless you changed your C# class to have an explicit name for the DataMember
[DataContract]
public class Person
{
[DataMember(Name="Name")]
public string FirstName {get; set;}
}
I'm not sure which error this would cause though. I Don't have enough first hand experience.
Do you think it could be an encoding problem? Have you tried using Encoding.UTF8 instead of Unicode?
All the examples I have seen using DataContractSerializer have used a UTF-8 encoding.
Encoding.Unicode is a UTF-16 encoding.
I can't find any documentation explicitly stating which encodings DataContractSerializer supports. I assume it would be smart enough to detect the proper encoding, but I don't know a whole whole lot about encodings. Maybe that isn't really possible in this instance.

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...)

Categories