Windows phone app, Windows.Web.Http.HttpClient post sample - c#

Long time searching for a sample on how to make a post call with parameters using Windows.Web.Http.HttpClient oHttpClient (that is not System.Net.Http.HttpClient !!), does some one have any?
Microsoft samples never use parameters, that I could see.

From yesterday, I have found how to solve this using Windows.Web.Http.HttpClient:
Windows.Web.Http.HttpClient oHttpClient = new Windows.Web.Http.HttpClient();
Uri uri= ... // some Url
string stringXml= "..."; // some xml string
HttpRequestMessage mSent = new HttpRequestMessage(HttpMethod.Post, uri);
mSent.Content =
new HttpStringContent(String.Format("xml={0}", stringXml),
Windows.Storage.Streams.UnicodeEncoding.Utf8);
HttpResponseMessage mReceived = await oHttpClient.SendRequestAsync(mSent,
HttpCompletionOption.ResponseContentRead);
// to get the xml response:
if (mReceived.IsSuccessStatusCode)
{
string strXmlReturned await mReceived.Content.ReadAsStringAsync();
}

I haven't done it with HtppClient but I did with WebRequest and json parameters in the request body:
WebRequest request = WebRequest.CreateHttp(url);
request.Method = "POST";
request.ContentType = "application/json";
using (var stream = await Task.Factory.FromAsync<Stream>(request.BeginGetRequestStream, request.EndGetRequestStream, null))
{
string postData = JsonConvert.SerializeObject(requestData);
byte[] postDataAsBytes = Encoding.UTF8.GetBytes(postData);
await stream.WriteAsync(postDataAsBytes, 0, postDataAsBytes.Length);
}
using (var response = await Task.Factory.FromAsync<WebResponse>(request.BeginGetResponse, request.EndGetResponse, null))
{
return await ProcessResponse(response);
}
BTW, I added this code to a portable library and now I can use it on Windows Phone 8, 8.1 and Windows 8.1.

Related

How to convert HttpWebRequest with POST method of a legacy program to HttpClient, using c#?

I have legacy code that uses HttpWebRequest and it works fine. Microsoft suggests that we use HttpClient. How can I modify it to use HttpClient, in c#?
string authText = "{ "AuthParams":{ "AuthToken":"TokenID", "FirmID":"MSFT", "SystemID":"Systems-Internal", "Version":"1.0", "UUID":"SystemsInternalAPIUser" }}";
var httpWebRequest = (HttpWebRequest)WebRequest.Create("http://msft.com/api/busnWebService/xbox-games");
JObject data = JObject.Parse(authText);
httpWebRequest.ContentType = "application/json";
httpWebRequest.Method = "POST";
using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
{
streamWriter.Write(data);
}
var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
var streamReader = new StreamReader(httpResponse.GetResponseStream());
string responseText = streamReader?.ReadToEnd();
(JsonConvert.DeserializeObject<CompRoot>(responseText).Data)
.Select(t => new CompanyClass
{
Ticker = t.Ticker,
}).ToList()
Since I can not try the solution with your payload and endpoint, something like the following should solve the problem without testing it.
string authText = "{\"AuthParams\":{\"AuthToken\":\"TokenID\",\"FirmID\":\"MSFT\",\"SystemID\":\"Systems - Internal\",\"Version\":\"1.0\",\"UUID\":\"SystemsInternalAPIUser\"}}";
var content = new StringContent(authText, Encoding.UTF8, "application/json");
using HttpClient client = new HttpClient();
var httpResponse = await client.PostAsync("http://msft.com/api/busnWebService/xbox-games", content);
string responseText = await httpResponse.Content.ReadAsStringAsync();
With HttpClinet you need to use async Task with await. I assume your mapping from the response should be the same. But you need to validate that.

Sending serialized data in Get/Post Requests

Hi I have a method in my webservice as follows
[HttpGet]
public HttpResponseMessage RegenerateReport(/*string reportObject*/)
{
var result = new HttpResponseMessage(HttpStatusCode.OK);
result.Content = new StringContent("Operation completed.");
return result;
}
It works fine but i actually want to be able to send a serialized JSON object to this function.
Alternatively, I tried using [HttpPost] tag on this function and calling from my code as follows
var data = Encoding.ASCII.GetBytes(JsonConvert.SerializeObject(obj));
string _BaseUrl = ConfigurationManager.AppSettings["WebAPIBaseURL"];
HttpWebRequest request = WebRequest.Create(string.Format("{0}{1}",
_BaseUrl,
"test/RegenerateReport?FileName=" + RCFileName)) as HttpWebRequest;
// Set type to POST
request.Method = "Post";
request.ContentType = "application/xml";
request.ContentLength = data.Length;
using (var stream = request.GetRequestStream())
{
stream.Write(data, 0, data.Length);
}
var response = (HttpWebResponse)request.GetResponse();
var responseString = new StreamReader(response.GetResponseStream()).ReadToEnd();
It returns
The requested resource does not support http method 'GET'.
Update
This error is now removed as i have added both tags [HttpGet] and [HttpPost] to my web method. Now the thing is how to pass serialized object to the web service method. Thanks!
If you want to submit some data in web service, you should always use [HttpPost].
I think your consumer is wrong and not doing a POST request. I typically use Microsoft.AspNet.WebApi.Client package and the sample code may look like this:
static async Task TestApiAsync()
{
using (var client = new HttpClient())
{
client.BaseAddress = new Uri("http://localhost:33854/");
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var result = await client.PostAsync("api/School", "hello", new JsonMediaTypeFormatter());
result.EnsureSuccessStatusCode();
// if it something returns
string resultString = await result.Content.ReadAsAsync<string>();
Console.WriteLine(resultString);
}
}
Just substitute the parameters for your need (URL, type, body)
As told by #MacakM, while HttpClient seems to be the ultimate solution I am sharing the exact code that worked for me.
HttpClient _client = new HttpClient();
var apiParams = new Dictionary<string, string>();
apiParams.Add("FileName", RCFileName ?? string.Empty);
string _BaseUrl = ConfigurationManager.AppSettings["WebAPIBaseURL"];
_client.BaseAddress = new Uri(_BaseUrl);
_client.DefaultRequestHeaders.Accept.Clear();
_client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var response = _client.GetAsync(string.Format("{0}{1}",
_BaseUrl,
"test/RegenerateReport?FileName=" + RCFileName)
);
if (response.IsCompleted)
_client.Dispose();//Dispose the client object

Windows-Universal https Post Xamarin Forms

I want to make a Json Post Request with my Windows Universal App.
I have it working in my Android and IOS.
public String DoServiceCall()
{
var request = (HttpWebRequest)WebRequest.Create(string.Format("{2}/{0}/{0}ServiceJson.svc/{1}", "Authentication", "Authenticate", "https://....."));
using (MemoryStream ms = new MemoryStream())
{
// create the request object
string requestString = JSONRequest;
byte[] requestData = Encoding.UTF8.GetBytes(requestString);
request.Method = "POST";
request.ContentType = "application/json; charset=UTF-8";
request.ContentLength = requestData.Length;
request.AllowAutoRedirect = false;
// add known cookies to request (needed for authentication)
CookieContainer requestCookies = new CookieContainer();
foreach (Cookie knownCookie in this._cookieCollection)
{
requestCookies.Add( knownCookie);
}
request.CookieContainer = requestCookies;
//For getting rid of the https Problem
ServicePointManager.ServerCertificateValidationCallback += (sender, cert, chain, sslPolicyErrors) => true;
using (Stream stream = request.GetRequestStream())
{
stream.Write(requestData, 0, requestData.Length);
}
// get response data
HttpWebResponse response = (HttpWebResponse) request.GetResponse();
string responseString = new StreamReader(response.GetResponseStream()).ReadToEnd();
return (responseString);
}
}
The Problem is that Windows Universal does not support.
request.ContentLength = requestData.Length;
request.AllowAutoRedirect = false;
requestCookies.Add( knownCookie); //with only one Argument
ServicePointManager.ServerCertificateValidationCallback += (sender, cert, chain, sslPolicyErrors) => true;
Neither does it support.
request.GetRequestStream())
(HttpWebResponse) request.GetResponse();
But that i could fix with async
await request.GetRequestStreamAsync())
(HttpWebResponse)await request.GetResponseAsync();
But without that 4 Lines i couldn´t get it working on Windows.
I just doesn´t get any Response.
Is there an Option to get it working on Windows 10 or is there an Working alternative.
So i finally found a solution.
Based on the Comment i tried the HttpClient.
But the Stanard Httpclient in the system namespace doesn`t support filter, which i need to get pass the SSL certificat problem.
Luckly in the Windows.Web.Http namespace, there is another HttpClient, which suppports filters.
The answer is the fully functional HttpClient Post Call.
public async void testcallwind()
{
List<HttpCookie> cookieCollection = new List<HttpCookie>();
HttpBaseProtocolFilter filter = new HttpBaseProtocolFilter();
HttpClient httpClient;
filter.IgnorableServerCertificateErrors.Add(ChainValidationResult.Untrusted);//Allow untrusted CA's
filter.IgnorableServerCertificateErrors.Add(ChainValidationResult.Expired);
// add known cookies to request (needed for authentication)
foreach (HttpCookie knownCookie in cookieCollection)
{
filter.CookieManager.SetCookie(knownCookie);
}
httpClient = new HttpClient(filter);
string resourceAddress = string.Format("https://...");
string requestString = "{\"request\":{\"CallerState\":null,...."}}";
byte[] requestData = Encoding.UTF8.GetBytes(requestString);
UnicodeEncoding en = new UnicodeEncoding();
IHttpContent content = new HttpStringContent(requestString, 0, "application/json");
Uri postBody = new Uri(resourceAddress);
var response = await httpClient.PostAsync(postBody, content);
httpClient.Dispose();
var test = response.Content;
}

Unauthorized error when trying to get Nest Access Token

Everything was working fine until a couple days ago, I started getting an Unauthorized error when trying to get a Nest Access Token. I've double checked and the client ID and client secret code are all correct. Any ideas on what could be causing it?
HttpWebRequest request = WebRequest.CreateHttp("https://api.home.nest.com/oauth2/access_token?");
var token = await request.GetValueFromRequest<NestToken>(string.Format(
"client_id={0}&code={1}&client_secret={2}&grant_type=authorization_code",
CLIENTID,
code.Value,
CLIENTSECRET));
public async static Task<T> GetValueFromRequest<T>(this HttpWebRequest request, string postData = null)
{
T returnValue = default(T);
if (!string.IsNullOrEmpty(postData))
{
byte[] requestBytes = Encoding.UTF8.GetBytes(postData);
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
using (var postStream = await request.GetRequestStreamAsync())
{
await postStream.WriteAsync(requestBytes, 0, requestBytes.Length);
}
}
else
{
request.Method = "GET";
}
var response = await request.GetResponseAsync();
if (response != null)
{
using (var receiveStream = response.GetResponseStream())
{
using (var reader = new StreamReader(receiveStream))
{
var json = await reader.ReadToEndAsync();
var serializer = new DataContractJsonSerializer(typeof(T));
using (var tempStream = new MemoryStream(Encoding.UTF8.GetBytes(json)))
{
return (T)serializer.ReadObject(tempStream);
}
}
}
}
return returnValue;
}
While I can't provide an answer I can confirm the same thing is happening to my iOS app in the same timeframe.
Taking my url and post values works fine using postman in chrome. Alamofire is throwing up error 401, as is native swift test code like yours.
Have Nest perhaps changed their https negotiation?
This turned out to be because of a fault on Nest's end which was later fixed.

WP8 - Login to Website and parse HTML from answer

I want to login to this site: http://subcard.subway.co.uk/de_cardholder/JSP/login_reg.jsp
And i found out that I have to send a POST request to the server and I also know that I have to work with this POST request:
POST /de_cardholder/servlet/SPLoginServlet HTTP/1.1
Host: subcard.subway.co.uk
language=de&userID=ID&password=PASSWORD&transIdentType=1&programID=6
And after the login I want to parse the HTML data. But how can I implement the POST request on WP in C# and is it as easy as I think?
Try this,
Uri RequestUri = new Uri("subcard.subway.co.uk/de_cardholder/servlet/SPLoginServlet HTTP/1.1?language=de&userID=ID&password=PASSWORD&transIdentType=1&programID=6", UriKind.Absolute);
string PostData = "";
WebRequest webRequest;
webRequest = WebRequest.Create(RequestUri);
webRequest.Method = "POST";
webRequest.ContentType = "text/xml";
HttpWebResponse response;
string Response;
using (response = (HttpWebResponse)await webRequest.GetResponseAsync()) ;
using (Stream streamResponse = response.GetResponseStream())
using (StreamReader streamReader = new StreamReader(streamResponse))
{
Response = await streamReader.ReadToEndAsync();
}
if(Response != null)
{
//data should be available in Response
}
var postRequest = (HttpWebRequest)WebRequest.Create("your Url here");
postRequest.ContentType = "application/x-www-form-urlencoded";// you can give the type of request content here
postRequest.Method = "POST";
if you have any data to be posted along with the request as part of content and not as part of URL itself you can add this. example:- ( language=de&userID=ID&password=PASSWORD&transIdentType=1&programID=6)
using (var requestStream = await postRequest.GetRequestStreamAsync())
{
byte[] postDataArray = Encoding.UTF8.GetBytes("your request data");
await requestStream.WriteAsync(postDataArray, 0, postDataArray.Length);
}
if you do not have any data to be a send as content ignore the above code
WebResponse postResponse = await postRequest.GetResponseAsync();
if (postResponse != null)
{
var postResponseStream = postResponse.GetResponseStream();
var postStreamReader = new StreamReader(postResponseStream);
string response = await postStreamReader.ReadToEndAsync();// Result comes here
}

Categories

Resources