I'm trying to perform a POST to a site using a WebRequest in C#. The site I'm posting to is an SMS site, and the messagetext is part of the URL. To avoid spaces in the URL I'm calling HttpUtility.Encode() to URL encode it.
But I keep getting an URIFormatException - "Invalid URI: The format of the URI could not be determined" - when I use code similar to this:
string url = "http://www.stackoverflow.com?question=a sentence with spaces";
string encoded = HttpUtility.UrlEncode(url);
WebRequest r = WebRequest.Create(encoded);
r.Method = "POST";
r.ContentLength = encoded.Length;
WebResponse response = r.GetResponse();
The exception occurs when I call WebRequest.Create().
What am I doing wrong?
You should only encode the argument, not the entire url, so try:
string url = "http://www.stackoverflow.com?question=" + HttpUtility.UrlEncode("a sentence with spaces");
WebRequest r = WebRequest.Create(url);
r.Method = "POST";
r.ContentLength = encoded.Length;
WebResponse response = r.GetResponse();
Encoding the entire url would mean the :// and the ? get encoded too. The encoded string is then no longer a valid url.
UrlEncode should only be used on the query string. Try this:
string query = "a sentence with spaces";
string encoded = "http://www.stackoverflow.com/?question=" + HttpUtility.UrlEncode(query);
The current version of your code is urlencoding the slashes and colon in the URL, which is confusing webrequest.
Related
I am using the Kodi API, to control my htpc via asp.net.
Especialy the functio named "Playlist.Add".
The Json I send is like this:
{"jsonrpc":"2.0","method":"Playlist.Insert","params":{"playlistid":0,"position":0,"item":{"file":"smb://server/Ferry Corsten/Beautiful/Ferry Corsten - Beautiful (Extended).mp3"}},"id":1}
This is working fine. But when there are some none english characters in the string like this:
{"jsonrpc":"2.0","method":"Playlist.Insert","params":{"playlistid":0,"position":0,"item":{"file":"smb://server/01-Zum Geburtstag viel Glück.mp3"}},"id":1}
It is just throwing a "RequestCanceled" Exception.
My c# source is like this:
HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(_url);
string authInfo = Convert.ToBase64String(Encoding.Default.GetBytes(_username + ":" + _password));
webRequest.Headers["Authorization"] = "Basic " + authInfo;
webRequest.Method = "POST";
webRequest.UserAgent = "KodiControl";
webRequest.ContentType = "application/json";
webRequest.ContentLength = json.Length;
using (var streamWriter = new StreamWriter(webRequest.GetRequestStream()))
{
streamWriter.Write(json);
streamWriter.Flush();
streamWriter.Close();
}
The Exception is thrown at streamWriter.Flush().
So what do I have to do to send this request?``
I suggest you look into Kodi addon unicode paths
Following that guide will help you prevent common problems with non-latin characters in Kodi.
Python only works with unicode strings internally, converting to a particular encoding on output. (or input)". To make string literals unicode by default, add
from __future__ import unicode_literals
Addon path
path = addon.getAddonInfo('path').decode('utf-8')
.decode('utf-8') tells kodi to decode the given function using utf-8.
Kodi's getAddonInfo returns an UTF-8 encoded string and we decode it an unicode.
Browse dialog
dialog = xbmcgui.Dialog()
directory = dialog.browse(0, 'Title' , 'pictures').decode('utf-8')
dialog.browse() returns an UTF-8 encoded string which perhaps contains some non latin characters. Therefore decode it to unicode!
I'm using the WebClient class to post a form, it looks like this.
string URI = "url here";
string myParameters = string.Format("Parameter1={0}&Parameter2={1}", var1, var2);
WebClient wc = new WebClient();
wc.Encoding = Encoding.UTF8;
wc.Headers["Content-type"] = "application/x-www-form-urlencoded";
string HtmlResult = wc.UploadString(URI, myParameters);
Which works great, but certain characters like the & obviously breaks it.
How do I format my parameters to not remove but still make illegal characters get through?
You need to UrlEncode your vars using HttpUtility.UrlEncode
string URI = "url here";
string myParameters = string.Format("Parameter1={0}&Parameter2={1}",
HttpUtility.UrlEncode(var1),
HttpUtility.UrlEncode(var2));
WebClient wc = new WebClient();
wc.Encoding = Encoding.UTF8;
wc.Headers["Content-type"] = "application/x-www-form-urlencoded";
string HtmlResult = wc.UploadString(URI, myParameters);
This will encode all illegal characters, not just &, BTW
when reading these, on the other side of the request, you'll probably need to also UrlDecode them MSDN
They need to be percent-encoded:
encodeURIComponent('&')
"%90k"
For example the URL would look like:
www.facebook.com?service_name=M%90k
I have the following code.
When my URL is google.com I get a proper reply from my WebRequest but when I give the URL of my REST API request my response returns null.
I use the same URL on my browser, it returns the correct response.
p.s.The code I hid with ######### is actually the key to my API that I'd rather not reveal.
//HttpWebRequest req = (HttpWebRequest)WebRequest.Create("http://www.google.com");
HttpWebRequest req = (HttpWebRequest)WebRequest.Create("http://#########:#se.api.anpdm.com/v1/mailinglists/1/10");
HttpWebResponse res = (HttpWebResponse)req.GetResponse();
Stream S_DataStream;
StreamReader SR_DataStream;
string s_ResponseString = "nothing";
if (res != null)
{
//Translate data from the Web-Response to a string
S_DataStream = res.GetResponseStream();
SR_DataStream = new StreamReader(S_DataStream, Encoding.UTF8);
s_ResponseString = SR_DataStream.ReadToEnd();
S_DataStream.Close();
}
Console.WriteLine(s_ResponseString);
I got it. I shouldn't have put the authentication key like that (###) in the url. I should have used credentials like this with the key as the username and an empty password.
req.Credentials = new NetworkCredential("#####################","");
I'm having issues to send POST data that includes characteres like "+" in the password field,
string postData = String.Format("username={0}&password={1}", "anyname", "+13Gt2");
I'm using HttpWebRequest and a webbrowser to see the results, and when I try to log in from my C# WinForms using HttpWebRequest to POST data to the website, it tells me that password is incorrect. (in the source code[richTexbox1] and the webBrowser1). Trying it with another account of mine, that does not contain '+' character, it lets me log in correctly (using array of bytes and writing it to the stream)
byte[] byteArray = Encoding.ASCII.GetBytes(postData); //get the data
request.Method = "POST";
request.Accept = "text/html";
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = byteArray.Length;
Stream newStream = request.GetRequestStream(); //open connection
newStream.Write(byteArray, 0, byteArray.Length); // Send the data.
newStream.Close(); //this works well if user does not includes symbols
From this Question I found that HttpUtility.UrlEncode() is the solution to escape illegal characters, but I can't find out how to use it correctly, my question is, after url-encoding my POST data with urlEncode() how do I send the data to my request correctly?
This is how I've been trying for HOURS to make it work, but no luck,
First method
string urlEncoded = HttpUtility.UrlEncode(postData, ASCIIEncoding.ASCII);
//request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = urlEncoded.Length;
StreamWriter wr = new StreamWriter(request.GetRequestStream(),ASCIIEncoding.ASCII);
wr.Write(urlEncoded); //server returns for wrong password.
wr.Close();
Second method
byte[] urlEncodedArray = HttpUtility.UrlEncodeToBytes(postData,ASCIIEncoding.ASCII);
Stream newStream = request.GetRequestStream(); //open connection
newStream.Write(urlEncodedArray, 0, urlEncodedArray.Length); // Send the data.
newStream.Close(); //The server tells me the same thing..
I think I'm doing wrong on how the url-encoded must be sent to the request, I really ask for some help please, I searched through google and couldn't find more info about how to send encoded url to an HttpWebRequest.. I appreciate your time and attention, hope you can help me. Thank you.
I found my answer using Uri.EscapeDataString it exactly solved my problem, but somehow I couldn't do it with HttpUtility.UrlEncode. Stackoverflowing around, I found this question that is about urlEncode method, in msdn it documentation tells that:
Encodes a URL string.
But I know now that is wrong if used to encode POST data (#Marvin, #Polity, thanks for the correction). After discarding it, I tried the following:
string postData = String.Format("username={0}&password={1}", "anyname", Uri.EscapeDataString("+13Gt2"));
The POST data is converted into:
// **Output
string username = anyname;
string password = %2B13Gt2;
Uri.EscapeDataString in msdn says the following:
Converts a string to its escaped representation.
I think this what I was looking for, when I tried the above, I could POST correctly whenever there's data including the '+' characters in the formdata, but somehow there's much to learn about them.
This link is really helpful.
http://blogs.msdn.com/b/yangxind/archive/2006/11/09/don-t-use-net-system-uri-unescapedatastring-in-url-decoding.aspx
Thanks a lot for the answers and your time, I appreciate it very much. Regards mates.
I'd recommend you a WebClient. Will shorten your code and take care of encoding and stuff:
using (var client = new WebClient())
{
var values = new NameValueCollection
{
{ "username", "anyname" },
{ "password", "+13Gt2" },
};
var url = "http://foo.com";
var result = client.UploadValues(url, values);
}
the postdata you are sending should NOT be URL encoded! it's formdata, not the URL
string url = #"http://localhost/WebApp/AddService.asmx/Add";
string postData = "x=6&y=8";
WebRequest req = WebRequest.Create(url);
HttpWebRequest httpReq = (HttpWebRequest)req;
httpReq.Method = WebRequestMethods.Http.Post;
httpReq.ContentType = "application/x-www-form-urlencoded";
Stream s = httpReq.GetRequestStream();
StreamWriter sw = new StreamWriter(s,Encoding.ASCII);
sw.Write(postData);
sw.Close();
HttpWebResponse httpResp =
(HttpWebResponse)httpReq.GetResponse();
s = httpResp.GetResponseStream();
StreamReader sr = new StreamReader(s, Encoding.ASCII);
Console.WriteLine(sr.ReadToEnd());
This uses the System.Text.Encoding.ASCII to encode the postdata.
Hope this helps,
On the MSDN site there is an example of some C# code that shows how to make a web request with POST'ed data. Here is an excerpt of that code:
WebRequest request = WebRequest.Create ("http://www.contoso.com/PostAccepter.aspx ");
request.Method = "POST";
string postData = "This is a test that posts this string to a Web server.";
byte[] byteArray = Encoding.UTF8.GetBytes (postData); // (*)
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = byteArray.Length;
Stream dataStream = request.GetRequestStream ();
dataStream.Write (byteArray, 0, byteArray.Length);
dataStream.Close ();
WebResponse response = request.GetResponse ();
...more...
The line marked (*) is the line that puzzles me. Shouldn't the data be encoded using the UrlEncode method rather than UTF8? Isn't that what application/x-www-form-urlencoded implies?
The sample code is misleading, because ContentType is set to application/x-www-form-urlencoded but the actual content is plain text. application/x-www-form-urlencoded is a string like this:
name1=value1&name2=value2
The UrlEncode function is used to escape especial characters like '&' and '=' so a parser doesn't consider them as syntax. It takes a string (media type text/plain) and returns a string (media type application/x-www-form-urlencoded).
Encoding.UTF8.GetBytes is used to convert the string (media type application/x-www-form-urlencoded in our case) into an array of bytes, which is what the WebRequest API expects.
As Max Toro indicated, the examples on the MSDN site are incorrect: a correct form POST requires the data to be URL encoded; since the data in the MSDN example does not contain any characters that would be changed by encoding, they are, in a sense, already encoded.
The correct code would have a System.Web.HttpUtility.UrlEncode call on the names and values of each name/value pair before combining them into the name1=value1&name2=value2 string.
This page was helpful: http://geekswithblogs.net/rakker/archive/2006/04/21/76044.aspx