HTTP post contentlength error - httpwebrequest

I have a script sending a multi part mime ie a a soap with attachments. I am using C# httpWebRequest class. I am getting an error that says the content length is required yet I am setting the content length dynamically in my code using webrequest's contentLength property. any ideas why this could be? thanx!
this is the code:
public void sendSOAPoverHttpVoda()
{
try
{
string xmlDoc = this.soapXml;
byte[] bytes;
bytes = Encoding.UTF8.GetBytes(xmlDoc);
long contentSize = bytes.Length;
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(conectionUrl);
req.SendChunked = true;
CredentialCache credentialCacheObj = new CredentialCache();
credentialCacheObj.Add(
new Uri(conectionUrl),
"Basic", new NetworkCredential("dddfff", "dddddd"));
credentialCacheObj.Add(new Uri(conectionUrl), "Digest", new NetworkCredential("dddfff", "dddddd"));
req.Credentials = credentialCacheObj;
req.Method = "POST";
req.ProtocolVersion = HttpVersion.Version11;
req.ContentLength = xmlDoc.Length;
req.ContentType = "multipart/related; boundary=\"----=cellsmart_mm7_SOAP\";type=\"text/xml\";Start=\"</cellsmart_mm7_submit>\"";
req.AllowWriteStreamBuffering = true;
req.Timeout = 20000;
req.Headers.Add("SOAPAction", "");
//req.Connection = "";
if (bytes != null)
{
using (Stream outputStream = req.GetRequestStream())
{
outputStream.Write(bytes, 0, xmlDoc.Length);
}
}
using (HttpWebResponse response = (HttpWebResponse)req.GetResponse())
{
Stream responseStream = response.GetResponseStream();
StreamReader reader = new StreamReader(responseStream);
string responseText = reader.ReadToEnd();
Console.WriteLine("Response received from URI : " + responseText);
Console.ReadLine();
}
Console.ReadLine();
}
catch (Exception ex)
{
Console.WriteLine("Error : " + ex.Message + "\n" + ex.StackTrace);
Console.ReadLine();
}
}
The error/exception i get is COntent length required (411)

You can't use both SendChunked=true and ContentLength. The easiest thing to do would be to use a chunked response and omit the ContentLength. You could also retain the ContentLength and omit the SendChunked if you want though.
In case you're not familiar with it, wikipedia has a nice description of chunking.

You declare contentLength as the length of the byte[] that you send ('bytes') and then you use the length of xmlDoc as the content length - which will give a different length than actual. Then you use the same xmlDoc.Length in outputStream.Write.
Why are you not using bytes.Length in both cases? Or contentLength which you've declared but never used, I believe that is your problem, you are sending xmlDoc.Length (Length of a string) for bytes.Length (length of a byte array converted from a string), so when the file is longer than expected by the sent length, the error returns.
Try this:
public void sendSOAPoverHttpVoda()
{
try
{
string xmlDoc = this.soapXml;
byte[] bytes;
bytes = Encoding.UTF8.GetBytes(xmlDoc);
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(conectionUrl);
req.SendChunked = true;
CredentialCache credentialCacheObj = new CredentialCache();
credentialCacheObj.Add(
new Uri(conectionUrl),
"Basic", new NetworkCredential("dddfff", "dddddd"));
credentialCacheObj.Add(new Uri(conectionUrl), "Digest", new NetworkCredential("dddfff", "dddddd"));
req.Credentials = credentialCacheObj;
req.Method = "POST";
req.ProtocolVersion = HttpVersion.Version11;
req.ContentLength = bytes.Length;
req.ContentType = "multipart/related; boundary=\"----=cellsmart_mm7_SOAP\";type=\"text/xml\";Start=\"</cellsmart_mm7_submit>\"";
req.AllowWriteStreamBuffering = true;
req.Timeout = 20000;
req.Headers.Add("SOAPAction", "");
//req.Connection = "";
if (bytes != null)
{
using (Stream outputStream = req.GetRequestStream())
{
outputStream.Write(bytes, 0, bytes.Length);
}
}
using (HttpWebResponse response = (HttpWebResponse)req.GetResponse())
{
Stream responseStream = response.GetResponseStream();
StreamReader reader = new StreamReader(responseStream);
string responseText = reader.ReadToEnd();
Console.WriteLine("Response received from URI : " + responseText);
Console.ReadLine();
}
Console.ReadLine();
}
catch (Exception ex)
{
Console.WriteLine("Error : " + ex.Message + "\n" + ex.StackTrace);
Console.ReadLine();
}
}

Related

Post a string to restful webservice in C#

I am provided a webservice url similar to:
http://ericdev35:7280/persons/persons/
and a username and password.
I want to make a post call on this web service from WPF application.
The data to be sent to the service is the first name and last name of a person in the format:
"fname=Abc&lname=Xyz"
How can I make a call for this in C#?
Here is the code that I have tried:
HttpWebRequest httpWebRequest = (HttpWebRequest) WebRequest.Create("http://ericdev35:7280/persons/persons/");
httpWebRequest.Method = "POST";
httpWebRequest.ContentType = "application/json";
httpWebRequest.Credentials = new NetworkCredential(username, password);
string data = "fname=Abc&lname=Xyz";
StreamWriter writer = new StreamWriter(httpWebRequest.GetRequestStream());
writer.Write(data);
writer.Close();
This does not give me any error but I cannot see the data that I have posted. Is there anything that needs to be corrected?
Is the Content Type correct?
This Method posts json.
After that it gets the response and deserialize the Json Object.
private static string PostJson<T1>(string p_url, string p_json, string p_method, out T1 p_target)
{
var httpWebRequest = (HttpWebRequest)WebRequest.Create(p_url);
httpWebRequest.UseDefaultCredentials = true;
httpWebRequest.ContentType = "application/json";
httpWebRequest.Method = p_method;
using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
{
streamWriter.Write(p_json);
streamWriter.Flush();
streamWriter.Close();
}
HttpWebResponse httpResponse;
try
{
httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
}
catch (WebException ex)
{
httpResponse = ex.Response as HttpWebResponse;
}
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
var a_result = streamReader.ReadToEnd();
//If you dont need a Json object delete anything behind here
try
{
p_target = JsonConvert.DeserializeObject<T1>(a_result);
}
catch { p_target = default(T1); }
return a_result;
}
}

The request was aborted could not create ssl/tls secure channel. httpwebrequest

I'm using an approach I found on Google that does not work as I hoped.
string resultxml = string.Empty;
#region First Link code
try
{
ServicePointManager.Expect100Continue = true;
ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3;
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);
//Header Settings
req.Method = "POST"; // Post method
req.ContentType = "text/xml";// content type
req.KeepAlive = false;
req.ProtocolVersion = HttpVersion.Version10;
//Certificate with private key
String certificateFileNameWithPath = "C:\\JPCertificates\\test.pfx";
String certificatePassword = "password";
X509Certificate2 cert = new X509Certificate2(certificateFileNameWithPath, certificatePassword);
req.ClientCertificates.Add(cert);
req.PreAuthenticate = true;
String XML = Xml;// "Test Message";//reader.ReadToEnd();
byte[] buffer = Encoding.ASCII.GetBytes(XML);
req.ContentLength = buffer.Length;
// Wrap the request stream with a text-based writer
Stream writer = req.GetRequestStream();
// Write the XML text into the stream
writer.Write(buffer, 0, buffer.Length);
writer.Close();
WebResponse rsp = req.GetResponse();
StreamReader responseStream = new StreamReader(rsp.GetResponseStream());
#endregion
}
catch (Exception ex)
{
throw ex;
}
return resultxml;
//Send the SOAP message StreamWriter stm = new StreamWriter(request.GetRequestStream(), Encoding.UTF8);
stm.Write(requestXML);
stm.Flush();
stm.Close();
//Send the SOAP message StreamWriter stm = new StreamWriter(request.GetRequestStream(), Encoding.UTF8);
stm.Write(requestXML);
stm.Flush();
stm.Close();

Error Code 551 while connecting a FTP server through .NET code

I am using the below c# code to connect the FTP server. Sometimes while sending the files it is getting the Error Code 551 with Description: Exception caught in sending FTP: The remote server returned an error: (551) Page type unknown.
I don't why this is happening.
Can anyone tell me what the issue is?
private bool sendFTP(string sDestPath, string sFileName, string sUserName, string sPassword, string sDomain, bool isProxyUsed, string sProxy, int nProxyPort, byte[] sData)
{
try
{
NetworkCredential nCred;
if (!sDomain.Equals(String.Empty))
{
nCred = new System.Net.NetworkCredential(sUserName, sPassword, sDomain);
}
else
{
nCred = new System.Net.NetworkCredential(sUserName, sPassword);
}
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(sDestPath + "//" + sFileName);
request.Method = WebRequestMethods.Ftp.UploadFile;
request.Credentials = nCred;
request.Proxy = new WebProxy();
if (isProxyUsed)
{
WebProxy p = new WebProxy(sProxy, nProxyPort);
p.Credentials = nCred;
WebRequest.DefaultWebProxy = p;
}
request.ContentLength = sData.Length;
Stream reqStream = request.GetRequestStream();
reqStream.Write(sData, 0, sData.Length);
reqStream.Close();
FtpWebResponse response = (FtpWebResponse)request.GetResponse();
return true;
}
catch (Exception objEx)
{
// Error
EventLog.WriteEntry("STCCommon", "Exception Caught:" + objEx.Message, EventLogEntryType.Error);
throw new Exception("Exception caught in sending FTP: " + objEx.Message);
}
}

2 exceptions when trying to make async HttpWebRequest

I am writing an MVC Web API the make async HttpWebRequest calls. I am getting 2 different exceptions. Below is the method I am using.
The 1st exception is: "This stream does not support seek operations." and it is happening on the responseStream.
The 2nd exception is: "timeouts are not supported on this stream" and that is happening on the MemoryStream content.
What am I doing wrong? I have been Googling but not really finding any solution.
Thanks,
Rhonda
private async Task GetHtmlContentAsync(string requestUri, string userAgent, string referrer, bool keepAlive, TimeSpan timeout, bool forceTimeoutWhileReading, string proxy, string requestMethod, string type)
{
//string to hold Response
string output = null;
//create request object
var request = (HttpWebRequest)WebRequest.Create(requestUri);
var content = new MemoryStream();
request.Method = requestMethod;
request.KeepAlive = keepAlive;
request.Headers.Set("Pragma", "no-cache");
request.Timeout = (Int32)timeout.TotalMilliseconds;
request.ReadWriteTimeout = (Int32)timeout.TotalMilliseconds;
request.Referer = referrer;
request.Proxy = new WebProxy(proxy);
request.UserAgent = userAgent;
try
{
using (WebResponse response = await request.GetResponseAsync().ConfigureAwait(false))
{
using (Stream responseStream = response.GetResponseStream())
{
if (responseStream != null)
{
await responseStream.CopyToAsync(content);
}
}
var sr = new StreamReader(content);
output = sr.ReadToEnd();
sr.Close();
}
}
catch (Exception ex)
{
output = string.Empty;
var message = ("The API caused an exception in the " + type + ".\r\n " + requestUri + "\r\n" + ex);
Logger.Write(message);
}
return output;
}
I fixed the issue by adding
content.Position = 0
before new StreamReader line. Now I just need to get it work with GZip compression.
Rhonda

How to pass array of byte to WCF service

I want to pass array of byte to WCF service from my windows phone app.The url is like below
"http:/serviceurl/Service1.svc/saverecord3?firstarray="
How can i do this?
Here a part of my code, which I am using to send post data to my server
HttpWebRequest req = (HttpWebRequest)WebRequest.Create("http:/serviceurl/Service1.svc/saverecord3");
req.Method = "POST";
req.ContentType = "text/xml; charset=utf-8"; //if your data is different, use a content type accordingly
string postData = #"firstarray=thedatatosend";
int length = arrayData.Length;
// Convert the string into a byte array.
byte[] byteArray = Encoding.UTF8.GetBytes(arrayData);
req.Headers[HttpRequestHeader.ContentLength] = byteArray.Length.ToString();
req.BeginGetRequestStream(ar =>
{
using (var requestStream = req.EndGetRequestStream(ar))
{
// Write the body of your request here
requestStream.Write(byteArray, 0, length);
}
req.BeginGetResponse(a =>
{
try
{
var response = req.EndGetResponse(a);
var responseStream = response.GetResponseStream();
using (var streamRead = new StreamReader(responseStream))
{
// Get the response message here
string responseString = streamRead.ReadToEnd();
//Do whatever you want here, with the response
}
}
catch (Exception e)
{
}
}, null);
}, null);