Am saving Webpages from webbrowser control to the directory like below code. Now i want to check all the webpages daily that is modified or not. if it is modified have to update or else leave it. here i tried something in console application.
static void Main(string[] args)
{
Uri myUri = new Uri("http://www.google.com");
// Create a new 'HttpWebRequest' object with the above 'Uri' object.
HttpWebRequest myHttpWebRequest = (HttpWebRequest)WebRequest.Create(myUri);
// Create a new 'DateTime' object.
DateTime targetDate = DateTime.Now;
// Set a target date of a week ago
targetDate.AddDays(-7.0);
myHttpWebRequest.IfModifiedSince = targetDate;
try
{
// Assign the response object of 'HttpWebRequest' to a 'HttpWebResponse' variable.
HttpWebResponse myHttpWebResponse = (HttpWebResponse)myHttpWebRequest.GetResponse();
Console.WriteLine("Response headers for recently modified page\n{0}\n", myHttpWebResponse.Headers);
Stream streamResponse = myHttpWebResponse.GetResponseStream();
StreamReader streamRead = new StreamReader(streamResponse);
Char[] readBuff = new Char[256];
int count = streamRead.Read(readBuff, 0, 256);
Console.WriteLine("\nThe contents of Html Page are : \n");
while (count > 0)
{
String outputData = new String(readBuff, 0, count);
Console.Write(outputData);
count = streamRead.Read(readBuff, 0, 256);
}
// Close the Stream object.
streamResponse.Close();
streamRead.Close();
// Release the HttpWebResponse Resource.
myHttpWebResponse.Close();
Console.WriteLine("\nPress 'Enter' key to continue.................");
Console.Read();
}
catch (WebException e)
{
if (e.Response != null)
{
if (((HttpWebResponse)e.Response).StatusCode == HttpStatusCode.NotModified)
{
Console.WriteLine("\nThe page has not been modified since " + targetDate);
Console.ReadLine();
}
else
Console.WriteLine("\nUnexpected status code = " + ((HttpWebResponse)e.Response).StatusCode);
Console.ReadLine();
}
else
Console.WriteLine("\nUnexpected Web Exception " + e.Message);
Console.ReadLine();
}
}
I tried this as console application and here i gave www.google.com straightly. but i want to check from my directory which is i saved from web browser control.
var filename1 = webBrowser1.Document.Title;
var path1 = (#"D:\Cache\" + filename1 + ".html");
if (mb != 1)
{
if (File.Exists(path1))
{
MessageBox.Show("Exist");
}
else
{
File.WriteAllText(path1, webBrowser1.Document.Body.Parent.OuterHtml, Encoding.GetEncoding(webBrowser1.Document.Encoding));
MessageBox.Show("Saved");
}
}
Anyone help me to finish this application. Thanks in Advance.
Related
I'm currently using stream reader and writer to read and write the files onto the webpage. Currently .html files are working but .jpg and images of any sorts do not post.
How would I be able to be able to serve up file like the mimetype mappings?
namespace wdd_assign_07_github
{
class Program
{
static void Main(string[] args)
{
//TcpListener server = null;
if (args == null)
{
Console.WriteLine("args is null");
}
else if (args.Length != 3)
{
Console.WriteLine("Not enough arguments");
}
else
{
//do nothing
}
string webRoot = args[0].Substring(args[0].LastIndexOf("=") + 1);
string webIP = args[1].Substring(args[1].LastIndexOf("=") + 1);
string webPort = args[2].Substring(args[2].LastIndexOf("=") + 1);
int numWebPort = Int32.Parse(webPort);
Int32 port = numWebPort;
TcpListener listener = new TcpListener(port);
listener.Start();
while (true)
{
//performing a blocking vall to accept requests
Console.WriteLine("Waiting for a connection");
TcpClient client = listener.AcceptTcpClient();
StreamReader sr = new StreamReader(client.GetStream());
StreamWriter sw = new StreamWriter(client.GetStream());
try
{
//client makes a request
//lets handle that request
string request = sr.ReadLine();
//lets print that out on our server console
Console.WriteLine(request);
//lets split that request
//[0]GET [1]PAGE [2]HTTPstring
string[] tokens = request.Split(' ');
string page = tokens[1];
//lets check if they requested the dedault page or not
if (page == "/")
{
page = "<H1>This is the default page</H1>";
}
//lets find the file now
StreamReader file = new StreamReader(webRoot + page);
sw.WriteLine("HTTP/1.0 200 OK\n");
//lets send the file
string data = file.ReadLine();
//while data doesnt equal null
while (data != null)
{
sw.WriteLine(data);
sw.Flush();
data = file.ReadLine();
}
}
catch (Exception e)
{
//error
sw.WriteLine("HTTP/1.0 404 OK\n");
sw.WriteLine("<H1>SORRY! We couldnt find your file</H1>");
sw.Flush();
}
client.Close();
}
}
}
}
There are multiple things you should consider:
Include Content-Type and
Content-Length
headers.
Use dictionary to define content types
var mappings = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase) {
{".jpg", "image/jpeg"},
{".html", "text/html"},
{".js", "application/javascript"},
// ...
};
// later in your method
var ext = Path.GetExtension(page);
var contentType = mappings[ext]; // may throw if mapping is missing
To use FileStream instead of StreamReader (at least for binary files like jpg and png)
I want to resume interrupted resumable upload using Google Drive v3 C# SDK.
The reason why I want this is to create resumable upload in Restful Web API.
There is google drive api instance in this RestAPI, so this is relaying chunk data from client program to google drive.
As you know, client program cannot upload whole file data at one time to Web API, so we need to resume interrupted resumable upload.
So my plan is here.
First, we need to create upload session and receive Session URI.
Second, Create Upload instance every time from returned URI and add chunk data.
Third, repeat 2nd process until EOF.
For this, I made test code, but it does not work at all.
var uploadStream = new System.IO.FileStream(UploadFileName, System.IO.FileMode.Open,
System.IO.FileAccess.Read);
var insert = service.Files.Create(new Google.Apis.Drive.v3.Data.File { Name = title }, uploadStream, ContentType);
Uri uploadUri = insert.InitiateSessionAsync().Result;
int chunk_size = ResumableUpload.MinimumChunkSize;
while (uploadStream.Length != uploadStream.Position)
{
byte[] temp = new byte[chunk_size];
uploadStream.Read(temp, 0, temp.Length);
MemoryStream stream = new MemoryStream(temp);
ResumableUpload resume_uploader = ResumableUpload.CreateFromUploadUri(uploadUri, stream);
resume_uploader.ChunkSize = chunk_size;
IUploadProgress ss = resume_uploader.Resume();
Console.WriteLine("Uploaded " + ss.BytesSent.ToString());
}
Frankly, I expected to receive 308 Resume Incomplete Code, but the result is different.
"Invalid request. According to the Content-Range header, the final size of the upload is 262144 byte(s). This does not match the expected size of 1193188 byte(s), which was specified in an earlier request."
This means that I need to create code that resumes interrupted resumable upload using Google Drive C# SDK.
Anybody can help me?
Finally, I solved issue. Exact code is below. Actually, I could not find any source code on Google, so I was so sad. Every developer who wants to solve this issue, use my code please. Hope you are fine. :)
public static async Task<Google.Apis.Drive.v3.Data.File> UploadSync(DriveService driveService, string filepath)
{
string destfilename = Path.GetFileName(filepath);
List<string> parents = new List<string>();
parents.Add("root");
// Prepare the JSON metadata
string json = "{\"name\":\"" + destfilename + "\"";
if (parents.Count > 0)
{
json += ", \"parents\": [";
foreach (string parent in parents)
{
json += "\"" + parent + "\", ";
}
json = json.Remove(json.Length - 2) + "]";
}
json += "}";
Debug.WriteLine(json);
Google.Apis.Drive.v3.Data.File uploadedFile = null;
try
{
System.IO.FileInfo info = new System.IO.FileInfo(filepath);
ulong fileSize = (ulong)info.Length;
var uploadStream = new System.IO.FileStream(filepath, System.IO.FileMode.Open, System.IO.FileAccess.Read);
var insert = driveService.Files.Create(new Google.Apis.Drive.v3.Data.File { Name = destfilename, Parents = new List<string> { "root" } }, uploadStream, "application/octet-stream");
Uri uploadUri = insert.InitiateSessionAsync().Result;
int chunk_size = ResumableUpload.MinimumChunkSize;
int bytesSent = 0;
while (uploadStream.Length != uploadStream.Position)
{
byte[] temp = new byte[chunk_size];
int cnt = uploadStream.Read(temp, 0, temp.Length);
if (cnt == 0)
break;
HttpWebRequest httpRequest = (HttpWebRequest)WebRequest.Create(uploadUri);
httpRequest.Method = "PUT";
httpRequest.Headers["Authorization"] = "Bearer " + ((UserCredential)driveService.HttpClientInitializer).Token.AccessToken;
httpRequest.ContentLength = (long)cnt;
httpRequest.Headers["Content-Range"] = string.Format("bytes {0}-{1}/{2}", bytesSent, bytesSent + cnt - 1, fileSize);
using (System.IO.Stream requestStream = httpRequest.GetRequestStreamAsync().Result)
{
requestStream.Write(temp, 0, cnt);
}
HttpWebResponse httpResponse;
try
{
httpResponse = (HttpWebResponse)httpRequest.GetResponse();
}
catch (WebException ex)
{
httpResponse = (HttpWebResponse)ex.Response;
}
if (httpResponse.StatusCode == HttpStatusCode.OK)
{ }
else if ((int)httpResponse.StatusCode != 308)
break;
bytesSent += cnt;
Console.WriteLine("Uploaded " + bytesSent.ToString());
}
if (bytesSent != uploadStream.Length)
{
return null;
}
// Try to retrieve the file from Google
FilesResource.ListRequest request = driveService.Files.List();
if (parents.Count > 0)
request.Q += "'" + parents[0] + "' in parents and ";
request.Q += "name = '" + destfilename + "'";
FileList result = request.Execute();
if (result.Files.Count > 0)
uploadedFile = result.Files[0];
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message);
}
return uploadedFile;
}
I have a small C# console app working that copies the results of a webrequest to a text file and then runs each command in that text file, saving the results to a separate text file.
Problem is, I have to make two requests to the same server, which I don't like doing. The problem is I can't seem to go to the beginning of the Stream/StreamReader after writing it to the text file, forcing me to make another request.
How do I do this with only one webrequest?
Thanks,
John
static void Main(string[] args)
{
// Set all variables
string epoUrl = "https://de-ser2012ecm:8443/remote/core.help.do";
string commandHelpPath = #"C:\Logs\AllCommandsHelp.txt";
string coreHelpPath = #"C:\Logs\CoreHelp.txt";
string epoUsername = "admin";
string epoPassword = "password";
string responseFromServer;
StringReader strReader;
try
{
// Get stream from webrequest
Stream coreStream = WebHelper.GetWebResponseStream(epoUrl, epoUsername, epoPassword);
StreamReader coreReader = new StreamReader(coreStream);
// Write core help page to text file
using (StreamWriter corefile = new StreamWriter(coreHelpPath, true, Encoding.UTF8))
{
responseFromServer = coreReader.ReadToEnd();
// Display the content.
corefile.Write(responseFromServer);
strReader = new StringReader(responseFromServer);
}
// Get new stream from webrequest
Stream commandStream = WebHelper.GetWebResponseStream(epoUrl, epoUsername, epoPassword);
StreamReader commandReader = new StreamReader(commandStream);
using (StreamWriter outfile = new StreamWriter(commandHelpPath, true, Encoding.UTF8))
{
while (!strReader.Peek().Equals(-1))
{
string streamLine = strReader.ReadLine();
string[] words = streamLine.Split(' ');
// Check if first string contains a period that's not at the end
if ((words[0].Contains(".")) & !(words[0].EndsWith(".")))
{
StreamReader helpReader = WebHelper.GetWebResponse(epoUrl + "?command=" + words[0], epoUsername, epoPassword);
string helpResponseFromServer = helpReader.ReadToEnd();
outfile.Write(helpResponseFromServer);
outfile.WriteLine("==============================");
}
}
}
}
catch (Exception ex)
{
Console.WriteLine("Main exception: " + ex.Message);
}
finally
{
// Close streams
//coreReader.Close();
//commandReader.Close();
Console.WriteLine("Press any key to continue");
Console.ReadKey();
}
}
And the GetWebResponseStream method:
public static Stream GetWebResponseStream(string url, string username, string password)
{
Stream dataStream = null;
try
{
// Set the credentials.
CredentialCache credentialCache = new CredentialCache();
credentialCache.Add(new System.Uri(url), "Basic", new System.Net.NetworkCredential(username, password));
ServicePointManager.ServerCertificateValidationCallback = (s, cert, chain, ssl) => true;
// Create a request for the URL.
WebRequest request = WebRequest.Create(url);
request.Credentials = credentialCache;
// Get the response.
WebResponse response = request.GetResponse();
// Get the stream containing content returned by the server.
dataStream = response.GetResponseStream();
return dataStream;
}
catch (Exception ex)
{
Console.WriteLine("GetWebResponse threw an exception: " + ex.Message);
return dataStream;
}
}
Thanks to Gildor for the suggestion that put me on the right track. I had the response, I just needed to copy that string into a StringReader. This automatically resets the cursor so you can read from the top! I updated the code to show the new fix. Thanks to everyone for the suggestions. John
My application uses a httpwebrequest to GET certain information from my WebAPI. What I'm trying to do is retry the request if the connection is lost or if there is no connection at all.
public static string httpsGET(string passedweburi, string BCO)
{
string content = "";
//GET method
HttpWebRequest HttpRequest = (HttpWebRequest)WebRequest.Create(passedweburi + BCO);
HttpRequest.Method = "GET";
//Response
HttpWebResponse response = (HttpWebResponse)HttpRequest.GetResponse();
StreamReader sr = new StreamReader(response.GetResponseStream(), System.Text.Encoding.GetEncoding("UTF-8"));
content = sr.ReadToEnd();
string resp = content.TrimStart('[').TrimEnd(']').TrimStart('"').TrimEnd('"');
if (resp == "\"The request is invalid.\"")
{
return "VALIDATE Me";
}
else
{
return resp;
}
}
It usually stops at the response variable then throws the exception from the method that calls this method, that there is no connection. I am thinking of making a while loop to make a countdown to reconnect for about an hour perhaps. Something like this:
int rt = 0;
while (rt < 60)
{
if (resp == "\"Unable to connect to the remote server.\"")
{
Console.Writeline("Connection Timed Out");
Console.Writeline("Re-establishing connection...");
DateTime startTime = DateTime.Now;
while (true)
{
if (DateTime.Now.Subtract(startTime).TotalMilliseconds > 60000)
break;
}
rt++;
Console.Writeline("Retrying " + rt.ToString() + " times");
}
if (rt >= 60)
{
Console.Writeline("Failed to reconnect.");
}
Any advise?
//this is by no means pretty, but im using your code verbatim
` public static string httpsGET(string passedweburi, string BCO)
{
string content = "";
//GET method
HttpWebRequest HttpRequest = (HttpWebRequest)WebRequest.Create(passedweburi + BCO);
HttpRequest.Method = "GET";
//Response
try
{
HttpWebResponse response = (HttpWebResponse)HttpRequest.GetResponse();
}
catch(Exception ex)
{
return "failed";
}
StreamReader sr = new StreamReader(response.GetResponseStream(), System.Text.Encoding.GetEncoding("UTF-8"));
content = sr.ReadToEnd();
string resp = content.TrimStart('[').TrimEnd(']').TrimStart('"').TrimEnd('"');
if (resp == "\"The request is invalid.\"")
{
return "VALIDATE Me";
}
else
{
return resp;
}
}
//calling your method
string resp = "";
while (rt < 60)
{
if (rt >= 60)
{
Console.Writeline("Failed to reconnect.");
}
resp = YourStaticObj.httpsGET("http://bla","bco")
if (resp == "failed")
{
Console.Writeline("Connection Timed Out");
Console.Writeline("Re-establishing connection...");
DateTime startTime = DateTime.Now;
System.Threading.Thread.Sleep(60000);
Console.Writeline("Retrying " + rt.ToString() + " times");
}
}
I was passing a large file in the first arg to SendXMLFile() below but, since it was causing the handheld device to "hang"/"freeze" I temporarily hard-coded a much smaller file (3 KB as opposed to 1121 KB) for testing.
The file does indeed exist (in the same folder as the .exe/.dll), as can be seen by this code:
// test with smaller file:
fileName = "DSD_v6666_3_20140310140737916.xml";
MessageBox.Show("Made it before file.Open");
using (FileStream fileTest = File.Open(fileName, FileMode.CreateNew))
{
fileTest.Write(info, 0, info.Length);
fileTest.Flush();
}
if (!File.Exists(fileName))
{
MessageBox.Show(String.Format("{0} does not seem to exist", fileName));
}
else
{
MessageBox.Show(String.Format("{0} DOES seem to exist", fileName));
}
string justFileName = Path.GetFileNameWithoutExtension(fileName);
String uri = String.Format(#"http://SHANNON2:21609/api/inventory/sendXML/gus/woodrow/{0}", justFileName).Trim();
SendXMLFile(fileName, uri, 500);
Here is the code that is then called, attempting to send the file:
public static string SendXMLFile(string xmlFilepath, string uri, int timeout)
{
// TODO: Remove after testing
String s = String.Format("xmlFilepath == {0}, uri == {1}, timeout == {2}", xmlFilepath, uri, timeout);
MessageBox.Show(s);
// </ TODO: Remove after testing
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
//request.KeepAlive = false; // should this be true? <== commented out as a test, but no diff in behavior
request.ProtocolVersion = HttpVersion.Version10;
request.ContentType = "application/xml";
request.Method = "POST";
StringBuilder sb = new StringBuilder();
// TODO: Remove after testing
MessageBox.Show("Made it to just before the StreamReader using");
using (StreamReader sr = new StreamReader(xmlFilepath))
{
// TODO: Remove after testing
MessageBox.Show("Made it just inside the StreamReader using"); // <= This is the last point reached
String line;
while ((line = sr.ReadLine()) != null)
{
// TODO: Remove after testing
MessageBox.Show(string.Format("line == {0}", line));
sb.Append("\r\n");
}
. . .
When I run this, I see:
"Made it before file.Open"
"DSD_v6666_3_20140310140737916.xml DOES seem to exist"
[The xmlFilepath, uri, and timout vals expected]
"Made it to just before the StreamReader using"
"Made it just inside the StreamReader using"
-- but not the "line == ..." message - it hangs, and I have to warm boot the device to bring it back from electronic limbo.
Is there a potential problem with the StreamReader code, or...???
UPDATE
I don't know whether this is a problem is in the data, or a differences I had to make in the code to get it to work in the Compact Framework. I have very similar code that works from a Winforms app:
public static string SendXMLFile(string xmlFilepath, string uri, int timeout)
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
request.KeepAlive = false;
request.ProtocolVersion = HttpVersion.Version10;
request.ContentType = "application/xml";
request.Method = "POST";
StringBuilder sb = new StringBuilder();
using (StreamReader sr = new StreamReader(xmlFilepath))
{
String line;
while ((line = sr.ReadLine()) != null)
{
sb.AppendLine(line);
}
byte[] postBytes = Encoding.UTF8.GetBytes(sb.ToString());
if (timeout < 0)
{
request.ReadWriteTimeout = timeout;
request.Timeout = timeout;
}
request.ContentLength = postBytes.Length;
try
{
Stream requestStream = request.GetRequestStream();
requestStream.Write(postBytes, 0, postBytes.Length);
requestStream.Close();
//using (var response = (HttpWebResponse)request.GetResponse())
//{
// return response.ToString();
//}
// alternate way, safe for older versions of .NET
HttpWebResponse response = null;
try
{
response = (HttpWebResponse)request.GetResponse();
}
finally
{
IDisposable disposableResponse = response as IDisposable;
if (disposableResponse != null) disposableResponse.Dispose();
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
request.Abort();
return string.Empty;
}
}
}
---called like so, passing the same file as a test case:
private void button20_Click(object sender, EventArgs e)
{
// Change the file name before each test
String fullFilePath = #"C:\HoldingTank\DSD_v6666_3_20140310140737916.xml";
string justFileName = Path.GetFileNameWithoutExtension(fullFilePath);
String uri = String.Format(#"http://localhost:21608/api/inventory/sendXML/su/su/{0}", justFileName);
SendXMLFile(fullFilePath, uri, 500);
}
UPDATE 2
I changed the code to use an XMLTextReader, and now I'm back to the err I was previously having, namely "(400) Bad Request" which is documented in most of its gory detail here.
Here is the new code, and what I now see:
public static bool WriteIt2( string fileName, string data, long fsize )
{
bool retVal = false;
int bytRd = 0; // if use this, change its name
string the_Msg = "";
if (File.Exists(fileName))
{
File.Delete(fileName);
}
Byte[] info = Encoding.UTF8.GetBytes(data);
// Testing with this relatively small file for now
fileName = "DSD_v6666_3_20140310140737916.xml";
MessageBox.Show("Made it before file.Open");
using (FileStream fileTest = File.Open(fileName, FileMode.CreateNew))
{
fileTest.Write(info, 0, info.Length);
fileTest.Flush();
}
if (!File.Exists(fileName))
{
MessageBox.Show(String.Format("{0} does not seem to exist", fileName));
} // I have never seen the msg above, but always saw the one below, so commented it out
else //<= always exists, so unnecessary
{
MessageBox.Show(String.Format("{0} DOES seem to exist", fileName));
}
string justFileName = Path.GetFileNameWithoutExtension(fileName);
String uri = String.Format(#"http://SHANNON2:21609/api/inventory/sendXML/su/su/{0}", justFileName).Trim();
SendXMLFile(fileName, uri, 500);
Now here's the code that actually does the reading, writing, and sending (or tries to):
public static string SendXMLFile(string xmlFilepath, string uri, int timeout)
{
String s = String.Format("xmlFilepath == {0}, uri == {1}, timeout == {2}", xmlFilepath, uri, timeout);
MessageBox.Show(s);
// </ TODO: Remove after testing
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
request.ProtocolVersion = HttpVersion.Version10;
request.ContentType = "application/xml";
request.Method = "POST";
StringBuilder sb = new StringBuilder();
MessageBox.Show("Made it to just before the StreamReader using");
StreamReader sr = new StreamReader(xmlFilepath);
MessageBox.Show("Made it past the StreamReader being constructed");
XmlTextReader reader = null;
reader = new XmlTextReader(sr);
while (reader.Read())
{
switch (reader.NodeType)
{
case XmlNodeType.Element: // The node is an Element.
sb.Append("<" + reader.Name);
while (reader.MoveToNextAttribute()) // Read attributes.
sb.Append(" " + reader.Name + "='" + reader.Value + "'");
sb.Append(">");
sb.Append(">");
break;
case XmlNodeType.Text: //Display the text in each element.
sb.Append (reader.Value);
break;
case XmlNodeType. EndElement: //Display end of element.
sb.Append("</" + reader.Name);
sb.Append(">");
break;
}
}
// TODO: Remove after testing
MessageBox.Show("Made it past the while loop");
MessageBox.Show(String.Format("sb first line is {0}", sb[0].ToString()));
MessageBox.Show(String.Format("sb tenth line is {0}", sb[9].ToString()));
byte[] postBytes = Encoding.UTF8.GetBytes(sb.ToString());
if (timeout < 0)
{
request.Timeout = timeout;
}
request.ContentLength = postBytes.Length;
try
{
Stream requestStream = request.GetRequestStream();
requestStream.Write(postBytes, 0, postBytes.Length);
requestStream.Close();
// This code for older versions of .NET from ctacke:
HttpWebResponse response = null;
try
{
response = (HttpWebResponse)request.GetResponse();
return response.ToString();
}
finally
{
IDisposable disposableResponse = response as IDisposable;
if (disposableResponse != null) disposableResponse.Dispose();
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
request.Abort();
return string.Empty;
}
}
What I see now when this runs:
0) "Made it before file.Open"
1) "DSD_v6666_3_20140310140737916.xml DOES seem to exist"
2) [ the xmlFilePath and other args - they are what is expected ]
3) "Made it to just before the StreamReader using"
4) "Made it past the StreamReader being constructed
5) "Made it past the while loop
6) "sb first line is "<"
7) "sb tenth line is ">"
8) "The remote server returned an error (400) Bad Request"
So at least it's no longer hanging, but I'm back to wondering why the server considers this a bad request.
I think you should return to basics:
public static string SendXMLFile(string xmlFilepath, string uri, int timeout)
{
using (var client = new WebClient())
{
client.Headers.Add("Content-Type", "application/xml");
byte[] response = client.UploadFile(uri, "POST", xmlFilepath);
return Encoding.ASCII.GetString(response);
}
}
and see what works and what the server thinks of your file.
When you really need a TimeOut then see this answer