I need to allow user to enter a remote API url with basic authentication/ or a static token to POST the data from my application to the URL at specified intervals.
I tried setting the "HEAD" only but it does the GET operation and throws 405 - Method Not Allowed error for all the requests.
I would like to know if there is any way to validate the url and the credentials with given POST url.
I understand I can valid the the url but my concern is to ensure that I need to validate the basic auth credentials entered by the user is also correct.
Try this-
try
{
WebRequest tRequest = WebRequest.Create("YOUR API URL");
tRequest.Method = "post";
tRequest.ContentType = "application/json";
var data = new
{
//REQUIERED PARAMETERIZED DATA
};
var serializer = new JavaScriptSerializer();
var json = serializer.Serialize(data);
Byte[] byteArray = Encoding.UTF8.GetBytes(json);
tRequest.Headers.Add(string.Format("Authorization: key={0}", ApplicationID));
tRequest.Headers.Add(string.Format("YOUR HEADER"));
tRequest.ContentLength = byteArray.Length;
using (Stream dataStream = tRequest.GetRequestStream())
{
dataStream.Write(byteArray, 0, byteArray.Length);
using (WebResponse tResponse = tRequest.GetResponse())
{
using (Stream dataStreamResponse = tResponse.GetResponseStream())
{
using (StreamReader tReader = new StreamReader(dataStreamResponse))
{
String sResponseFromServer = tReader.ReadToEnd();
str = sResponseFromServer;
}
}
}
}
}
catch (Exception ex)
{
str = ex.Message;
}
Related
I need help.
I have a method: PostCustomer
HttpResponseMessage PostCustomer([FromBody] CustomerRec Logs, [FromBody] Customer customer)
Now my problem is how will I able to test this through fiddler
I know I need to call for example:
"//api/customer/PostCustomer"
But how will I pass parameters on this?
I'm testing this using fiddler.
I'm not sure if you are asking how to build the url request (passing the parameters for your method through url)
If that's it, it should be like this
api/customer/PostCustomer/?FirstParameter=Example&SecondParemeter=Example2
If you mean the request itself
string postData = string.Format("?FirstParameter=" + txt_First.Text + "&SecondParemeter=" + txt_Last.Text);
byte[] data = Encoding.UTF8.GetBytes(postData);
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("..../api/customer/PostCustomer"/" + postData);
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
request.Accept = "application/json";
request.ContentLength = data.Length;
using (Stream requestStream = request.GetRequestStream())
{
requestStream.Write(data, 0, data.Length);
}
try
{
using (WebResponse response = request.GetResponse())
{
var responseValue = string.Empty;
// grab the response
using (var responseStream = response.GetResponseStream())
{
using (var reader = new StreamReader(responseStream))
{
responseValue = reader.ReadToEnd(); // read the full response
}
}
if (responseValue != "")
{
//Do something here if response is not empty
}
}
}
catch (WebException ex)
{
// Handle error
}
PS: Can't comment on post because it asks for 50+ reputation...
I'm trying to call http://genderize.io/ , but i'm getting an error from .NET saying:
{"You must provide a request body if you set ContentLength>0 or SendChunked==true. Do this by calling [Begin]GetRequestStream before [Begin]GetResponse."}
How would I call this web service "http://api.genderize.io/?name=peter" from C# and get a JSON string back?
HttpWebRequest request;
string postData = "name=peter"
URL = "http://api.genderize.io/?"
Uri uri = new Uri(URL + postData);
request = (HttpWebRequest)WebRequest.Create(uri);
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = postData.Length;
request.AllowAutoRedirect = true;
UTF8Encoding enc = new UTF8Encoding();
string result = string.Empty;
HttpWebResponse Response;
try
{
using (Response = (HttpWebResponse)request.GetResponse())
{
using (Stream responseStream = Response.GetResponseStream())
{
using (StreamReader readStream = new StreamReader(responseStream, Encoding.UTF8))
{
return readStream.ReadToEnd();
}
}
}
}
catch (Exception ex)
{
Debug.WriteLine("Error: " + ex.Message);
throw ex;
}
You are making the call to the service using POST method, reading through the comments area in http://genderize.io/ the author states that only GET method requests are allowed.
Stroemgren: Yes, this is confirmed. Only HTTP GET request are allowed.
This answer probably would be better as a comment, but I don't have enough reputation :(
I am verifying my ios in app purchase receipt on my server using C# web service
I got receipt as string by doing below in Xcode:
- (void) completeTransaction: (SKPaymentTransaction *)transaction
{
NSString* receiptString = [[NSString alloc] initWithString:transaction.payment.productIdentifier];
NSLog(#"%#",receiptString);
NSURL *receiptURL = [[NSBundle mainBundle] appStoreReceiptURL];
NSData *receipt = [NSData dataWithContentsOfURL:receiptURL];
NSString *jsonObjectString = [receipt base64EncodedStringWithOptions:0];
}
and I am sending that string(receipt) to my C# web service as parameter.
Here is my web service method:
[WebMethod(Description = "Purchase Item Verify")]
public string PurchaseItem(string receiptData)
{
string returnmessage = "";
try
{
var json = "{ 'receipt-data': '" + receiptData + "'}";
ASCIIEncoding ascii = new ASCIIEncoding();
byte[] postBytes = Encoding.UTF8.GetBytes(json);
HttpWebRequest request;
request = WebRequest.Create("https://sandbox.itunes.apple.com/verifyReceipt") as HttpWebRequest;
request.Method = "POST";
request.ContentType = "application/json";
request.ContentLength = postBytes.Length;
Stream postStream = request.GetRequestStream();
postStream.Write(postBytes, 0, postBytes.Length);
postStream.Close();
var sendresponse = (HttpWebResponse)request.GetResponse();
string sendresponsetext = "";
using (var streamReader = new StreamReader(sendresponse.GetResponseStream()))
{
sendresponsetext = streamReader.ReadToEnd();
}
returnmessage = sendresponsetext;
}
catch (Exception ex)
{
ex.Message.ToString();
}
return returnmessage;
}
It always return {"status":21002}.
I have been searching for two days , but still can't find out the solution. Can someone help me, what am i wrong ?
**I am testing on sandbox that is why i use sandbox URL. I can verify the transaction receipt within my app.
I got solution
The final code that works for me is:
public string PurchaseItem(string receiptData)
{
string returnmessage = "";
try
{
// var json = "{ 'receipt-data': '" + receiptData + "'}";
var json = new JObject(new JProperty("receipt-data", receiptData)).ToString();
ASCIIEncoding ascii = new ASCIIEncoding();
byte[] postBytes = Encoding.UTF8.GetBytes(json);
// HttpWebRequest request;
var request = System.Net.HttpWebRequest.Create("https://sandbox.itunes.apple.com/verifyReceipt");
request.Method = "POST";
request.ContentType = "application/json";
request.ContentLength = postBytes.Length;
//Stream postStream = request.GetRequestStream();
//postStream.Write(postBytes, 0, postBytes.Length);
//postStream.Close();
using (var stream = request.GetRequestStream())
{
stream.Write(postBytes, 0, postBytes.Length);
stream.Flush();
}
// var sendresponse = (HttpWebResponse)request.GetResponse();
var sendresponse = request.GetResponse();
string sendresponsetext = "";
using (var streamReader = new StreamReader(sendresponse.GetResponseStream()))
{
sendresponsetext = streamReader.ReadToEnd().Trim();
}
returnmessage = sendresponsetext;
}
catch (Exception ex)
{
ex.Message.ToString();
}
return returnmessage;
Spending two and half days just to change a method. Thanks GOD.
Here's an alternative asynchronous implementation using HTTPClient:
public static async Task<string> CheckReceiptWithAppStore()
{
string responseStr = null;
string uri = "https://sandbox.itunes.apple.com/verifyReceipt";
string receiptData = // Get your receipt from wherever you store it
var json = new JObject(new JProperty("receipt-data", receiptData),
new JProperty("password", "paste-your-shared-secret-here")).ToString();
using (var httpClient = new HttpClient())
{
if (receiptData != null)
{
HttpContent content = new StringContent(json);
try
{
Task<HttpResponseMessage> getResponse = httpClient.PostAsync(uri, content);
HttpResponseMessage response = await getResponse;
responseStr = await response.Content.ReadAsStringAsync();
}
catch (Exception e)
{
Console.WriteLine("Error verifying receipt: " + e.Message);
}
}
}
return responseStr;
}
The shared secret is not required for non-subscription based purchases.
For managing subscriptions, #Jerry Naing's answer also requires the provision of your shared secret (can be retrieved/generated from iTunes Connect). Easiest way to include this is just to add an additional property in the line defining the json var.
var json = new JObject(new JProperty("receipt-data", receiptData), new JProperty("password", "put_your_shared_secret_here")).ToString();
Failing to provide the shared secret will result in a 21004 status response.
This code example was also helpful to me and may help others: For C# developers there is a useful open-source project called APNS-Sharp which includes receipt verification code that works in ASP.NET. In particular, the Receipt.cs and ReceiptVerification.cs files in the Jdsoft.Apple.AppStore directory
Found it from this page about Xamarin: inapp purcasing ios Transactions and Verification
I am trying to get a response from Base API, but i keep getting "500 Internal Server Error" error. I want to get at least 401 HTTP Response which means that authentication call has failed. Here is a description of using Base API authentication:
http://dev.futuresimple.com/api/authentication
And here is my code:
public string Authenticate()
{
string result = "";
string url = "https://sales.futuresimple.com/api/v1/";
string email = "mail#mail.com";
string password = "pass";
string postData = "email=" + email + "&password=" + password;
HttpWebRequest request = null;
Uri uri = new Uri(url + "authentication.xml");
request = (HttpWebRequest)WebRequest.Create(uri);
request.Method = "POST";
request.ContentType = "application/xml";
request.ContentLength = postData.Length;
using (Stream writeStream = request.GetRequestStream())
{
UTF8Encoding encoding = new UTF8Encoding();
byte[] bytes = encoding.GetBytes(postData);
writeStream.Write(bytes, 0, bytes.Length);
writeStream.Close();
}
try
{
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
using (Stream responseStream = response.GetResponseStream())
{
using (StreamReader readStream = new StreamReader(responseStream, Encoding.UTF8))
{
result = readStream.ReadToEnd();
}
}
}
}
catch (WebException ex)
{
ex = ex;
}
return result;
}
You're setting the ContentType to application/xml - this is the type of the request body. The body you're sending (string postData = "email=" + email + "&password=" + password;) is form-encoded instead of xml. Just skipping the line request.ContentType = "application/xml"; should do the trick. Alternatively you can encode your request body as xml.
I am struggling to develop a C# class to login to cPanel on a web host (Hostgator).
In PHP it is quite easy using the Curl extension as follows:
$url = "http://mysite.com:2082/";
$c = curl_init($url);
curl_setopt($c, CURLOPT_USERPWD, 'user:password');
curl_setopt($c, CURLOPT_RETURNTRANSFER, 1);
$result = curl_exec($c);
if ($result === false)
$result = curl_error($c);
curl_close($c);
file_put_contents('log.txt', $result);
//print_r($result);
Now here is my C# class with the various attempts to make it work commented out:
class HTTPHandler
{
public static string Connect (string url, string userName, string password)
{
string result;
try
{
// An initial # symbol in the password must be escaped
if (password.Length > 0)
if (password[0] == '#')
password = "\\" + password;
// Create a request for the URL.
WebRequest request = WebRequest.Create(url);
request.PreAuthenticate = true;
request.Credentials = new NetworkCredential(userName, password);
/*
var credCache = new CredentialCache();
credCache.Add(new Uri(url), "Basic",
new NetworkCredential(userName, password));
request.Credentials = credCache;
*/
//request.Method = "POST";
//request.ContentType = "application/x-www-form-urlencoded";
/*
// Create POST data and convert it to a byte array.
string postData = string.Format("user={0}&pass={1}", userName, password);
byte[] byteArray = Encoding.UTF8.GetBytes(postData);
request.ContentLength = byteArray.Length;
request.ContentType = "application/x-www-form-urlencoded";
Stream dataStream = request.GetRequestStream();
dataStream.Write(byteArray, 0, byteArray.Length);
dataStream.Close();
*/
// Get the response.
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
// Get the stream containing content returned by the server.
Stream dataStream = response.GetResponseStream();
// Open the stream using a StreamReader for easy access.
StreamReader reader = new StreamReader(dataStream);
// Display the content.
result = string.Format("Server response:\n{0}\n{1}", response.StatusDescription, reader.ReadToEnd());
// Cleanup the streams and the response.
reader.Close();
dataStream.Close();
response.Close();
}
catch (Exception e)
{
result = string.Format("There was an error:\n{0}", e.Message);
}
return result;
}
}
}
But I keep getting an error 401 (Unauthorized) at the GetResponse stage.
When I compare the $_SERVER vars in my local host test page between the PHP and C# submissions, I get the same data apart from the sender port being a bit different. The crucial PHP_AUTH_USER and PHP_AUTH_PW are the same.
My OS is Windows 7 64 bit and I am using Visual C# 2010.
I guess the solution is really simple, but so far I am baffled. But a relative newbie to C#. I hope somebody can help.
You don't really need to set PreAuthenticate, just let the request figure it out. Also I would suggest using HttpWebRequest instead of WebRequest. The main difference is that you can set CookieContainer property to enable cookies. This is a bit confusing since by default it will have cookies disabled and all you need to do is to set it to new CookieContainer(); to enable cookies for your request.
This matters because of the redirects that happen during authentication and the auth cookie that records the fact that you successfully authenticated.
Also a coding style note: please make sure to wrap all the IDisposables (such as response, stream and reader) in the using() statement.
Also I am unclear why are you escaping # in the password. Request should take care of all your encoding needs automagically.
Complete sample code:
var request = WebRequest.CreateHttp(url);
request.Credentials = new NetworkCredential(username, password);
request.CookieContainer = new CookieContainer(); // needed to enable cookies
using (var response = (HttpWebResponse)request.GetResponse())
using (var reader = new StreamReader(response.GetResponseStream(), Encoding.GetEncoding(response.CharacterSet)))
return string.Format("Server response:\n{0}\n{1}", response.StatusDescription, reader.ReadToEnd());
edit: Sorry for all the edits. I was writing code by memory and was struggling a bit with getting the encoding part right.
This is using System.Web where I had to set the project properties to use the full .NET Framework 4 to gain access to this assembly for the HttpUtility and add a reference to System.Web in References.
I didn't test all the overloaded methods but the main thing is the cPanel connection where the authentication credentials are added to the http header when a userName is present.
Also, for cPanel I needed to set request.AllowAutoRedirect = false; so that I control page by page access since I didn't manage to capture cookies.
Here is the code for the HTTP Helper Class that I came up with:
class HTTPHandler
{
// Some default settings
const string UserAgent = "Bot"; // Change this to something more meaningful
const int TimeOut = 1000; // Time out in ms
// Basic connection
public static string Connect(string url)
{
return Connect(url, "", "", UserAgent, "", TimeOut);
}
// Connect with post data passed as a key : value pair dictionary
public static string Connect(string url, Dictionary<string, string> args)
{
return Connect(url, "", "", UserAgent, ToQueryString(args), TimeOut);
}
// Connect with a custom user agent specified
public static string Connect(string url, string userAgent)
{
return Connect(url, "", "", userAgent, "", TimeOut);
}
public static string Connect(string url, string userName, string password, string userAgent, string postData, int timeOut)
{
string result;
try
{
// Create a request for the URL.
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
if (userAgent == null)
userAgent = UserAgent;
request.UserAgent = userAgent;
request.Timeout = timeOut;
if (userName.Length > 0)
{
string authInfo = userName + ":" + password;
authInfo = Convert.ToBase64String(Encoding.Default.GetBytes(authInfo));
request.Headers["Authorization"] = "Basic " + authInfo;
request.AllowAutoRedirect = false;
}
if (postData.Length > 0)
{
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
// Create POST data and convert it to a byte array.
byte[] byteArray = Encoding.UTF8.GetBytes(postData);
request.ContentLength = byteArray.Length;
using (Stream dataStream = request.GetRequestStream())
{
dataStream.Write(byteArray, 0, byteArray.Length);
}
}
// Get the response.
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
// Get the stream containing content returned by the server.
Stream dataStream = response.GetResponseStream();
// Open the stream using a StreamReader for easy access.
using (StreamReader reader = new StreamReader(dataStream))
{
result = string.Format("Server response:\n{0}\n{1}", response.StatusDescription, reader.ReadToEnd());
}
}
}
catch (Exception e)
{
result = string.Format("There was an error:\n{0}", e.Message);
}
return result;
}
public static string ToQueryString(Dictionary<string, string> args)
{
List<string> encodedData = new List<string>();
foreach (KeyValuePair<string, string> pair in args)
{
encodedData.Add(HttpUtility.UrlEncode(pair.Key) + "=" + HttpUtility.UrlEncode(pair.Value));
}
return String.Join("&", encodedData.ToArray());
}
}