52

I'm writing a small API-connected application in C#.

I connect to a API which has a method that takes a long string, the contents of a calendar(ics) file.

I'm doing it like this:

HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(URL); request.Method = "POST"; request.AllowAutoRedirect = false; request.CookieContainer = my_cookie_container; request.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"; request.ContentType = "application/x-www-form-urlencoded"; string iCalStr = GetCalendarAsString(); string strNew = "&uploadfile=true&file=" + iCalStr; using (StreamWriter stOut = new StreamWriter(request.GetRequestStream(), System.Text.Encoding.ASCII)) { stOut.Write(strNew); stOut.Close(); } 

This seems to work great, until I add some specific HTML in my calendar.

If I have a '&nbsp' somewhere in my calendar (or similar) the server only gets all the data up to the '&'-point, so I'm assuming the '&' makes it look like anything after this point belongs to a new parameter?

How can I fix this?

1
  • Encode the string before sending it? Commented Apr 14, 2011 at 15:29

3 Answers 3

59

First install "Microsoft ASP.NET Web API Client" nuget package:

 PM > Install-Package Microsoft.AspNet.WebApi.Client 

Then use the following function to post your data:

public static async Task<TResult> PostFormUrlEncoded<TResult>(string url, IEnumerable<KeyValuePair<string, string>> postData) { using (var httpClient = new HttpClient()) { using (var content = new FormUrlEncodedContent(postData)) { content.Headers.Clear(); content.Headers.Add("Content-Type", "application/x-www-form-urlencoded"); HttpResponseMessage response = await httpClient.PostAsync(url, content); return await response.Content.ReadAsAsync<TResult>(); } } } 

And this is how to use it:

TokenResponse tokenResponse = await PostFormUrlEncoded<TokenResponse>(OAuth2Url, OAuth2PostData); 

or

TokenResponse tokenResponse = (Task.Run(async () => await PostFormUrlEncoded<TokenResponse>(OAuth2Url, OAuth2PostData))) .Result 

or (not recommended)

TokenResponse tokenResponse = PostFormUrlEncoded<TokenResponse>(OAuth2Url, OAuth2PostData).Result; 
Sign up to request clarification or add additional context in comments.

5 Comments

Not sure if I am missing something, but this way the request hangs
What is OAuth2PostData ?
@Kiquenet - When you post a request with Content-Type of application/x-www-form-urlencoded it usually required some data. I copied the sample code from a code that was written for OAuth2 authentication so the varible name is OAuth2PostData. The name is not important, it is simply a variable that holds data. It is basically a list of KeyValuePair<string, string>.
Sorry but how to use TokenResponse class? Add using Microsoft.Bot.Schema; ?
@PhamX.Bach - TokenResponse is your model. Define a class that matches the return schema of the Web API which you are calling. It is a simple POCO.
34

Since your content-type is application/x-www-form-urlencoded you'll need to encode the POST body, especially if it contains characters like & which have special meaning in a form.

Try passing your string through HttpUtility.UrlEncode before writing it to the request stream.

Here are a couple links for reference.

2 Comments

The second link goes to some Japanese site!
Thank you! For me I just had to convert my string strCallString = System.Web.HttpUtility.UrlEncode(strCallString) before posting it with .ContentType = "application/x-www-form-urlencoded"
10

As long as the server allows the ampresand character to be POSTed (not all do as it can be unsafe), all you should have to do is URL Encode the character. In the case of an ampresand, you should replace the character with %26.

.NET provides a nice way of encoding the entire string for you though:

string strNew = "&uploadfile=true&file=" + HttpUtility.UrlEncode(iCalStr); 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.