How do I convert Byte Array response from WebClient to Xml? - c#

I am calling a third party service and they send the response as Xml. However, as I am using WebClient to call the service the response I get is a byte array.
var client = new WebClient();
var result = client.UploadValues(post_url, data);
result is a byte array. How do I convert it to XML to read the response given by the third party service?

You can turn the bytes into a string:
string xml = Encoding.UTF8.GetString(result);
and then parse it :
XDocument doc = XDocument.Parse(xml);

Use a MemoryStream:
using (var stream = new MemoryStream(result))
{
var doc = XDocument.Load(stream);
...
}

Related

How to read Json response into Document object of Document AI in C#

I am trying to read json file from cloud storage and trying to convert that into Google.Cloud.DocumentAI.V1.Document.
I have done POC, but its throwing exception Google.Protobuf.InvalidProtocolBufferException: 'Protocol message end-group tag did not match expected tag.'
First I am reading .Json file into MemoryStream and trying to Merge in to Document.
using Google.Cloud.DocumentAI.V1;
public static void StreamToDocument()
{
byte[] fileContents = File.ReadAllBytes("C:\\upload\\temp.json");
using (Stream memoryStream = new MemoryStream(fileContents))
{
Document doc = new Document();
var byteArray = memoryStream;
doc.MergeFrom(byteArray);
}
}
Error Message I am getting is
Is there any other way I can achieve this ?
The code that you've specified there expects the data to be binary protobuf content. For JSON, you want:
string json = File.ReadAllText("C:\\upload\\temp.json");
Document document = Document.Parser.ParseJson(json);

Parse Xml response from a get method in C# using Linq

I have following url which returns me XML response in c#:
http://www.bnr.ro/files/xml/years/nbrfxrates2017.xml
Now, i want to retrieve the currency in Euro for my date which is present as a paramater in my function. I want to use Linq but i have some problems
My function:
public static void getXml(String year, String data)
{
WebClient webClient = new WebClient();
string url = "http://www.bnr.ro/files/xml/years/nbrfxrates" + year + ".xml";
HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
HttpWebResponse response = request.GetResponse() as HttpWebResponse;
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(response.GetResponseStream());
XElement xe = XElement.Load(response.GetResponseStream());
var x = (from e in xe.Elements("Cube")
where e.Attribute("date").Value.Equals(data)
select e.Element("Rate") into p
where p.Element("currency").Value.Equals(data)
select p.Value);
Console.WriteLine(x.ToString());
}
My error is:
The root element is missing on XElement xe =
XElement.Load(response.GetResponseStream());
Method GetResponseStream returns a stream:
Gets the stream that is used to read the body of the response from the
server.
You cannot read this stream twice. When you load XmlDocument it reads data from network stream and closes it releasing the connection. When you try to load XElement from the closed stream, you get an error.
You should read response stream only once - e.g. into string or into MemoryStream:
string xml;
using(var reader = new StreamReader(r.GetResponseStream()))
xml = reader.ReadToEnd();
Note: It's not clear why you need XmlDocument if you are using linq to xml.

How to parse the output from the web service which gives out JSON as output format. And I am using REST

How do I parse the output i.e., responseText?
var httpResponse = (HttpWebResponse)request.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
//read response
var responseText = streamReader.ReadToEnd();
return responseText;
}
And, I know that string is the return type which I have specified as mentioned below.
public string InvokeRequest(RESTInvokeClass objInvoke)
I think the complete output(some 100 lines) which is in the JSON format is completely displaying as a single string stopping me to parse the output.
My question is:
How to receive the output so that I can parse through it?
If you just want to serialize the reponse text to an object that you can traverse through, you can do something like:
JavaScriptSerializer jsSerializer = new JavaScriptSerializer();
var riClass = jsSerializer.DeserializeObject(responseText);
foreach(var item in riClass)
{
//Do something with this item
}

how to display a string from a rest webservice in windows forms?

how can display a string from a rest webservice in windows forms my xml looks like this:
<string>whatever</string>
How can you display that in a textbox in win forms?
If I try
string uri = string.Format("etc/{0}/{1} Sad.Text, Happy.Text");
XDocument xDoc = XDocument.Load(uri);
string mystring = xDoc.Element("String").Value;
textBox1.Text = mystring;
You get an object reference error?
XML elements are case-sensitive. Try,
string mystring = xDoc.Element("string").Value;
A better way to solve the problem is to not use XML to return a simple string. The media type text/plain is designed to do that. If you are using Microsoft's ASP.NET Web API just return
return new HttpResponseMessage() {
Content = new StringContent("etc/{0}/{1} Sad.Text, Happy.Text")
};
and on the client (using this http://nuget.org/Packages/system.net.http) do,
var httpClient = new HttpClient();
textBox1.Text = httpClient.GetAsync(uri).Result.Content.ReadAsString();
I would use XmlSerializer to get the information out of XML returned by the web service. I am assuming that your XML is just in a string. You could do something like this for your simple example, but this would also work for more complex objects returned by a REST web service.
XmlSerializer xs = new XmlSerializer ( typeof ( string ) );
MemoryStream memoryStream = new MemoryStream(StringToUTF8ByteArray(restResult));
XmlTextWriter xmlTextWriter = new XmlTextWriter(memoryStream, Encoding.UTF8);
string textBoxVal = xs.Deserialize(memoryStream);

upload XML -> read unicode stream and convert it

I have a fileupload control where i can upload xml documents.
The XML files will be encoded in unicode format. I want to convert them to UTF8, so they can render as a proper xml file.
Im saving the uploaded file in a hiddenfield as a hex string and sends it to a generic handler. What i want is a result that i can create an xml from. At the moment my string looks like this:
"??<\0?\0x\0m\0l\0 \0v\0e\0r\0s\0i\0o\0n\0=\0\"\01\0.\00\0\"\0 \0e\0n\0c\0o\0d\0i\0n\0g\0=\0\"\0I\0S\0O\0-
Instead of
<?xml version="1.0".. etc
Code:
if (fileUpload.PostedFile.ContentType == "text/xml")
{
Stream inputstream = fileUpload.PostedFile.InputStream;
byte[] streamAsBytes = (ConvertStreamToByteArray(inputstream));
string stringToSend = BitConverter.ToString(streamAsBytes);
xmlstream.Value = stringToSend;
sendXML.Visible = true;
infoLabel.Text = "<b>Selected XML: </b>" + fileUpload.PostedFile.FileName;
}
handler.ashx:
if (HttpContext.Current.Request.Form["xmldata"] != null)
{
HttpContext.Current.Response.ContentType = "text/xml";
HttpContext.Current.Response.ContentEncoding = Encoding.UTF8;
string xmlstring = HttpContext.Current.Request.Form["xmldata"];
byte[] data = xmlstring.Split('-').Select(b => Convert.ToByte(b, 16)).ToArray();
string complete = System.Text.ASCIIEncoding.ASCII.GetString(data);
XmlDocument doc = new XmlDocument();
doc.LoadXml(complete);
HttpContext.Current.Response.Write(doc.InnerXml);
}
Thanks!
It's not at all clear that you really should do this. XML files can declare their own encoding, and it looks like yours is declaring an encoding starting with "ISO" (that's where the data you've given us stops). That's probably not UTF-8.
Basically, I don't think you should be treating the data as text in handler.ashx. Just get XmlDocument to parse it from a stream. It's not really clear exactly how your upload code is sending the data, but you should try to mess with it as little as possible.
It's possible that your current code would actually work fine if you just changed this:
string complete = System.Text.ASCIIEncoding.ASCII.GetString(data);
XmlDocument doc = new XmlDocument();
doc.LoadXml(complete);
to this:
XmlDocument doc = new XmlDocument();
doc.Load(new MemoryStream(data));
However, the hex part is pretty ugly. If you really need to represent the binary data as text, I'd strongly recommend using Base64 instead of hex:
string text = Convert.ToBase64String(binary);
...
byte[] binary = Convert.FromBase64String(text);
... there's no need to convert each byte separately and split the string on hyphens etc.

Categories