How can I write an XML on my hard drive to GetRequestStream - c#

I need to post raw xml to a site and read the response. With the following code I keep getting an "Unknown File Format" error and I'm not sure why.
XmlDocument sampleRequest = new XmlDocument();
sampleRequest.Load(#"C:\SampleRequest.xml");
byte[] bytes = Encoding.UTF8.GetBytes(sampleRequest.ToString());
string uri = "https://www.sample-gateway.com/gw.aspx";
req = WebRequest.Create(uri);
req.Method = "POST";
req.ContentLength = bytes.Length;
req.ContentType = "text/xml";
using (var requestStream = req.GetRequestStream())
{
requestStream.Write(bytes, 0, bytes.Length);
}
// Send the data to the webserver
rsp = req.GetResponse();
XmlDocument responseXML = new XmlDocument();
using (var responseStream = rsp.GetResponseStream())
{
responseXML.Load(responseStream);
}
I am fairly certain my issue is what/how I am writing to the requestStream so..
How can I modify that code so that I may write an xml located on the hard drive to the request stream?

ok instead of doing sampleRequest.ToString(), you should use sampleRequest.OuterXml, and that would do the magic, you were sending "System.Xml.XmlDocument" instead of the Xml
XmlDocument sampleRequest = new XmlDocument();
sampleRequest.Load(#"C:\SampleRequest.xml");
//byte[] bytes = Encoding.UTF8.GetBytes(sampleRequest.ToString());
byte[] bytes = Encoding.UTF8.GetBytes(sampleRequest.OuterXml);

Two things:
First, whenever you're trying to diagnose a problem with an HTML response, you should always examine what the response stream actually contains. If you had in this case, you would have seen that it contains System.Xml.XmlDocument, which would have told you what was wrong pretty much immediately.
Second, in an application with any kind of transaction volume, you're not going to want to load a static XML file into an XmlDocument before putting it in the response stream; your program's spending time and memory building something that you don't need. (It's even worse than that in your case; your approach not only parses the XML into a DOM object, it then makes an in-memory copy of its OuterXml property when you encode it as UTF-8. Also, do you really need to be doing that?) Instead, you should create a FileStream object and use one of the techniques in this answer to copy it to the response stream.

Related

Get content of HttpWebResponse while debugging

I'm trying to run sequential requests to a web api url every 10 seconds to log changes in the data returned. The code snippet looks like this:
using (Stream objStream = response.GetResponseStream())
{
query result = (query)serializer.Deserialize(objStream);
Console.WriteLine(result.results.quote.Name + " " + result.results.quote.Ask);
objStream.Flush();
objStream.Close();
}
Every now and then an InvalidOperationException is thrown when running the deserialiation with the message saying that the XML document is badly formated. In an effort to isolate the problem I'm trying to find the "raw" response content in debug mode using the autos/locals/watch view, but I really can't find it.
I can find the response header and a lot of other information and as far as I can see this looks okay with one exception; the content-length which shows -1. I'm not sure if this is something that I should care about really but since I can't find the response "body" I can't help being suspicious about it.
So my real question here is: how can I find the "body" inside a HttpWebResponse or Stream object?
And the side question: Is the content-length with value -1 something to be bothered about.
If you read the entire contents from the stream and store it in a variable before deserializing it, you should be able to see the contents while debugging
For debugging i would suggest you replicate the response into string and that way you watch it.
using (Stream objStream = response.GetResponseStream())
{
StreamReader sr = new StreamReader(objStream);
string response = sr.ReadToEnd();
objStream.Seek(0,SeekOrigin.Begin); // Get the pointer back to the begining.
query result = (query)serializer.Deserialize(objStream);
Console.WriteLine(result.results.quote.Name + " " + result.results.quote.Ask);
objStream.Flush(); // remove
objStream.Close();//remove
}
I would also recommend to remove:
objStream.Flush();
objStream.Close();
when using 'using' statement it calls Dispose() (IDisposable()), which will eventauly close the stream by itself .

Parsing XML in a C# Application?

Right now, I am getting a Google search's XML. However, the XML doc is so big, I can't find anything anywhere. I am wondering how I can find the answer on Google. By that, I mean when you Google "Capital of Florida" the box at the top says Tallahassee. I want to access that information but I am unsure how.
var request = (HttpWebRequest)WebRequest.Create(url);
request.Method = "GET";
var response = request.GetResponse();
var rstream = response.GetResponseStream();
var sr = new StreamReader(rstream);
var json = sr.ReadToEnd();
Console.WriteLine(json.ToString());
The last Console.Writeline obviously just shoots out a huge monster of an XML doc
See this it uses LINQ to extract a piece of info from XML documents https://coderwall.com/p/qghcqw
if you are requesting HTML, a good way to parse the data is using HtmlAgilityPack
http://htmlagilitypack.codeplex.com/

How to make Stream.Write() output in UTF-8 format

My issue is this:
I am generating and uploading a SQL file using ASP.NET, but after the file is saved to the FTP server, characters like ü are changed to &uul;, ø to ø and so on... How can I prevent this from happening? I don't want the file to be formatted with ASCII code, but with UTF-8.
The code that generates and uploads the file looks like this:
//request = the object to be made an request out of.
Stream requestStream = request.GetReguestStream();
var encoding = new UTF8Encoding();
//fileContent is the string to be saved in the file
byte[] buffer = encoding.GetBytes(fileContent);
requestStream.Write(buffer, 0, buffer.Length);
requestStream.Close();
As you can see I've tried to use the System.Text.UTF8Encoding, but it doesn't work.
Remember, with streams you can almost always wrap the streams as necessary. If you want to write UTF-8 encoded content you wrap the request stream in a StreamWriter with the correct encoding:
using (Stream requestStream = request.GetRequestStream())
using (StreamWriter writer = new StreamWriter(requestStream, Encoding.UTF8)) {
writer.Write(fileContent);
}
Since you say you're uploading to a web service be sure to set your content encoding as well. Since you haven't posted where the request object comes from, I'll assume it's a normal HttpWebRequest.
With a HttpWebRequest you would tell the server what the content encoding is by using the ContentType property.
request.ContentType = "text/plain;charset=utf-8";
As others have mentioned, though, the FTP transfer itself may be breaking it too. If you can, make sure it's transferred in binary mode, not ASCII mode.
Put it in debug and look at what gets put in 'buffer' after encoding.GetBytes() is called. This will verify if it's the rx side causing it.

After transmission of text files blank lines appears in them

EDIT: Filezilla caused the problem, when i download files back from server it added new lines. I'm sorry for confusion.
This method upload files to ftp server and it's work fine, but in text files uploaded to server blank lines appear after every line("cr lf" appear), for example:
File:
First line
Second line
Third line
Uploaded file:
First line
Second line
Third line
Origin and uploaded files accordingly have different sizes, non-text files are the same.
Code:
private void sendFile(string In, string Out)
{
FtpWebRequest request = (FtpWebRequest) WebRequest.Create("ftp://domain//" + Out);
request.Method = WebRequestMethods.Ftp.UploadFile;
request.Credentials = new NetworkCredential("username", "password");
FileStream sourceStream = new FileStream(In, FileMode.Open, FileAccess.Read, FileShare.Read);
byte[] fileContents = new byte[sourceStream.Length];
sourceStream.Read(fileContents, 0, (int) sourceStream.Length);
sorceStream.Close();
request.ContentLength = fileContents.Length;
Stream requestStream = request.GetRequestStream();
requestStream.Write(fileContents, 0, fileContents.Length);
requestStream.Close();
}
How can i fix this?
EDIT: As the answer below doesn't seem to have helped (but I'm leaving it there for posterity as it shows better code) here are the next diagnostics steps I'd check:
How are you viewing the files? If at all possible, get onto the server directly rather than fetching the files again via a web browser or whatever.
What's the type of FTP server you're connecting to? Maybe there's a known issue.
Have you tried looking at what's actually being sent via Wireshark?
Have you tried sending the same files via a normal FTP client?
You should set FtpWebRequest.UseBinary to true in order to preserve the exact file contents. Otherwise the two systems will try to figure out line endings themselves, changing line terminators as they see fit. I very rarely think that's a good idea. (EDIT: UseBinary is actually true by default, but this sounds like the kind of problem introduced by using text mode... it certainly does no harm to make this explicit.)
Additionally:
You should be disposing of your FileStream via a using statement
You should be disposing of the request stream via a using statement
You should be taking note of the result of Stream.Read - it needn't always read the whole of the requested data in one go
You can either use File.ReadAllBytes to simply read the complete file data in one go, or use Stream.CopyTo (if you're using .NET 4) to copy the FileStream to the request stream (which won't set the content length, of course; I don't know whether this is a problem)
You're never calling GetResponse; it's unclear exactly what happens if you never fetch the response of an FtpWebRequest
Your parameter names don't match .NET naming conventions, and aren't very descriptive
So I would probably use:
private void SendFile(string inputFile, string outputPath)
{
FtpWebRequest request = (FtpWebRequest) WebRequest.Create
("ftp://domain//" + outputPath);
request.Method = WebRequestMethods.Ftp.UploadFile;
request.UseBinary = true;
request.Credentials = new NetworkCredential("username", "password");
byte[] fileContents = File.ReadAllBytes(inputFile);
request.ContentLength = fileContents.Length;
using (Stream requestStream = request.GetRequestStream())
{
requestStream.Write(fileContents, 0, fileContents.Length);
}
// This *may* be necessary in order to validate that everything has happened
using (WebResponse response = request.GetResponse())
{
}
}
Its strange. I face the same problem and I was unable to fix it until I did not provide an extension in file. For Example if my file name was
abcfile
then I make it abcfile.dat and after that it shows me the uploaded file as actual file. I again upload file with abcfile.txt but this time again empty line problem appear in my uploaded file.
I suggest that you must provide extension to your file any except .txt.
The system that you're sending to uses different line endings to what your system uses. I can assume, because you get an extra line, that you're on Windows, and it uses CRLF endings. The system you're sending to recognises CR and LF as separate endings, so you get the extra lines.
For text, truncate the LF or the CR, see what happens. I have no clue about the differing file sizes.
In the top menu of FileZilla, set:
Transfer menu > Transfer type > binary
In the top menu of FileZilla, set:
Transfer menu > Transfer type > binary
It's working for me.

Pass through XML from another website

I am trying to pass through some XML from an external website.
What is the best way of doing this, through c# webpage or asp.MVC?
I tend to use something like this for working with external XML documents / RSS feeds etc:
string sURL = ".....";
// Create a request for the URL.
WebRequest oRequest = WebRequest.Create(sUrl);
// Get the response.
WebResponse oResponse = oRequest.GetResponse();
// Get the stream containing content returned by the server.
Stream oDataStream = oResponse.GetResponseStream();
// Open the stream using a StreamReader for easy access.
StreamReader oReader = new StreamReader(oDataStream, System.Text.Encoding.Default);
// Read the content.
string sXML = oReader.ReadToEnd();
// Convert string to XML
XDocument oFeed = XDocument.Parse(sXML);
Either should be fine. MVC is probably easiest (in terms of getting a raw response), but you could do the same in regular ASP.NET just by using a handler (possibly .ashx), or just by clearing the response.

Categories

Resources