So I have an api that I want to call to. The first call is an ahoy call and in the body of the request I need to send the ship_type, piratename and my piratepass. I then want to read the response which has my treasure booty that i will use for later.
I'm able to do this with web request. but i feel like there is a better way to do it with webclient.
(way I currently do it in webrequest)
//Credentials for the Pirate api
string piratename = "IvanTheTerrible";
string piratepass= "YARRRRRRRR";
string URI = "https://www.PiratesSuperSecretHQ.com/sandyShores/api/respectmyauthority";
WebRequest wr = WebRequest.Create(URI);
wr.Method = "POST";
wr.ContentType = "application/x-www-form-urlencoded";
string bodyData = "ship_type=BattleCruiser&piratename=" + piratename + "&piratepass=" + piratepass;
ASCIIEncoding encoder = new ASCIIEncoding();
byte[] byte1 = encoder.GetBytes(bodyData);
wr.ContentLength = byte1.Length;
//writes the body to the request
Stream newStream = wr.GetRequestStream();
newStream.Write(byte1, 0, byte1.Length);
newStream.Close();
WebResponse wrep = wr.GetResponse();
string result;
using (var reader = new StreamReader(wrep.GetResponseStream()))
{
result = reader.ReadToEnd(); // do something fun...
}
Thanks in advance either way.
You can do with this simple code
Uri uri = new Uri("yourUri");
string data = "yourData";
WebClient client = new WebClient();
var result = client.UploadString(uri, data);
Remember that you can use UploadStringTaskAsync if you want to be async
You can try like below as well:
public String wcPost(){
Map<String, String> bodyMap = new HashMap();
bodyMap.put("key1","value1");
WebClient client = WebClient.builder()
.baseUrl("domainURL")
.build();
String responseSpec = client.post()
.uri("URI")
.headers(h -> h.setBearerAuth("token if any"))
.body(BodyInserters.fromValue(bodyMap))
.exchange()
.flatMap(clientResponse -> {
if (clientResponse.statusCode().is5xxServerError()) {
clientResponse.body((clientHttpResponse, context) -> {
return clientHttpResponse.getBody();
});
return clientResponse.bodyToMono(String.class);
}
else
return clientResponse.bodyToMono(String.class);
})
.block();
return responseSpec;
}
Related
I am new to MVC and C#, so sorry if this question seems too basic.
For a HttpPost Controller like below, how do to call this method directly from a client-side program written in C#, without a browser (NOT from a UI form in a browser with a submit button)? I am using .NET 4 and MVC 4.
I am sure the answer is somehwere on the web, but haven't found one so far. Any help is appreciated!
[HttpPost]
public Boolean PostDataToDB(int n, string s)
{
//validate and write to database
return false;
}
For example with this code in the server side:
[HttpPost]
public Boolean PostDataToDB(int n, string s)
{
//validate and write to database
return false;
}
You can use different approches:
With WebClient:
using (var wb = new WebClient())
{
var data = new NameValueCollection();
data["n"] = "42";
data["s"] = "string value";
var response = wb.UploadValues("http://www.example.org/receiver.aspx", "POST", data);
}
With HttpRequest:
var request = (HttpWebRequest)WebRequest.Create("http://www.example.org/receiver.aspx");
var postData = "n=42&s=string value";
var data = Encoding.ASCII.GetBytes(postData);
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
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();
With HttpClient:
using (var client = new HttpClient())
{
var values = new List<KeyValuePair<string, string>>();
values.Add(new KeyValuePair<string, string>("n", "42"));
values.Add(new KeyValuePair<string, string>("s", "string value"));
var content = new FormUrlEncodedContent(values);
var response = await client.PostAsync("http://www.example.org/receiver.aspx", content);
var responseString = await response.Content.ReadAsStringAsync();
}
With WebRequest
WebRequest request = WebRequest.Create ("http://www.example.org/receiver.aspx");
request.Method = "POST";
string postData = "n=42&s=string value";
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 ();
//Response
WebResponse response = request.GetResponse ();
Console.WriteLine (((HttpWebResponse)response).StatusDescription);
dataStream = response.GetResponseStream ();
StreamReader reader = new StreamReader (dataStream);
string responseFromServer = reader.ReadToEnd ();
Console.WriteLine (responseFromServer);
reader.Close ();
dataStream.Close ();
response.Close ();
see msdn
You can use
First of all you should return valid resutl:
[HttpPost]
public ActionResult PostDataToDB(int n, string s)
{
//validate and write to database
return Json(false);
}
After it you can use HttpClient class from Web Api client libraries NuGet package:
public async bool CallMethod()
{
var rootUrl = "http:...";
bool result;
using (var client = new HttpClient())
{
client.BaseAddress = new Uri(_rootUrl);
var response= await client.PostAsJsonAsync(methodUrl, new {n = 10, s = "some string"});
result = await response.Content.ReadAsAsync<bool>();
}
return result;
}
You can also use WebClient class:
[HttpPost]
public Boolean PostDataToDB(int n, string s)
{
//validate and write to database
return false;
}
public async bool CallMethod()
{
var rootUrl = "http:...";
bool result;
using (var client = new WebClient())
{
var col = new NameValueCollection();
col.Add("n", "1");
col.Add("s", "2");
var res = await client.UploadValuesAsync(address, col);
string res = Encoding.UTF8.GetString(res);
result = bool.Parse(res);
}
return result;
}
If you decide to use HttpClient implementation. Do not create and dispose of HttpClient for each call to the API. Instead, re-use a single instance of HttpClient. You can achieve that declaring the instance static or implementing a singleton pattern.
Reference: https://aspnetmonsters.com/2016/08/2016-08-27-httpclientwrong/
How to implement singleton (good starting point, read the comments on that post): https://codereview.stackexchange.com/questions/149805/implementation-of-a-singleton-httpclient-with-generic-methods
Hopefully below code will help you
[ActionName("Check")]
public async System.Threading.Tasks.Task<bool> CheckPost(HttpRequestMessage request)
{
string body = await request.Content.ReadAsStringAsync();
return true;
}
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 tring to pull categories from my store on BigCommerce via API.
When I try my credentials at API Console;
https://developer.bigcommerce.com/console
it is working fine, but I when send credentials via C# post request it does not work.
I am receiving [{"status":401,"message":"No credentials were supplied in the request."}]
My code is like;
List<PostCredential> postCredentials = new List<PostCredential>();
postCredentials.Add(new PostCredential { name = "store_url", value = ApiPath });
postCredentials.Add(new PostCredential { name = "username", value = Username });
postCredentials.Add(new PostCredential { name = "api_key", value = ApiToken });
JavaScriptSerializer serializer = new JavaScriptSerializer();
string serialize = serializer.Serialize(postCredentials);
const string requestUrl = "https://myteststore1234.mybigcommerce.com/api/v2/categories.json";
StringBuilder postData = new StringBuilder();
postData.Append(serialize);
string postRequest = PostRequest(requestUrl, postData.ToString());
public static string PostRequest(string url, string postData)
{
HttpWebRequest httpWReq = (HttpWebRequest)WebRequest.Create(url);
ASCIIEncoding encoding = new ASCIIEncoding();
byte[] data = encoding.GetBytes(postData);
httpWReq.Method = "POST";
httpWReq.ContentType = "application/x-www-form-urlencoded";
httpWReq.ContentLength = data.Length;
using (Stream stream = httpWReq.GetRequestStream())
{
stream.Write(data, 0, data.Length);
}
HttpWebResponse response = (HttpWebResponse)httpWReq.GetResponse();
Stream responseStream = response.GetResponseStream();
if (responseStream != null)
{
string responseString = new StreamReader(responseStream).ReadToEnd();
return responseString;
}
return null;
}
is there any workaround for this?
WebHeaderCollection wHeader = new WebHeaderCollection();
wHeader.Clear();
//wHeader.Add("username:test");
//wHeader.Add("password:4afe2a8a38fbd29c32e8fcd26dc51f6d9b5ab99b");
//wHeader.Add("u","test:4afe2a8a38fbd29c32e8fcd26dc51f6d9b5ab99b");
string Username = "test";
string ApiToken = "4afe2a8a38fbd29c32e8fcd26dc51f6d9b5ab99b";
string sUrl = "https://store-bwvr466.mybigcommerce.com/api/v2/brands.json"; //txtstoreurl.Text.ToString() + "/api/v2/products.json";
HttpWebRequest wRequest = (HttpWebRequest)System.Net.HttpWebRequest.Create(sUrl);
wRequest.Credentials = new NetworkCredential(Username, ApiToken);
wRequest.ContentType = "application/json"; //' I don't know what your content type is
//wRequest.Headers = wHeader;
wRequest.Method = "GET";
HttpWebResponse wResponse = (HttpWebResponse)wRequest.GetResponse();
string sResponse = "";
using (StreamReader srRead = new StreamReader(wResponse.GetResponseStream()))
{
sResponse = srRead.ReadToEnd();
MessageBox.Show(sResponse);
}
After some research I found out I need to pass parameters like this;
httpWReq.Method = "GET";
httpWReq.ContentType = "application/json";
httpWReq.ContentLength = data.Length;
httpWReq.Credentials = new NetworkCredential(Username, ApiToken);
I'm working with Yandex Disk API (http://api.yandex.com/disk/doc/dg/reference/propfind_space-request.xml).
Having trouble with adding property in the request body (quota-available-bytes and quota-used-bytes)
public static string SpaceInfo(string path)
{
// Authorization.
HttpWebRequest webReq = (HttpWebRequest)WebRequest.Create("https://webdav.yandex.ru/");
webReq.Accept = "*/*";
webReq.Headers.Add("Depth: 0");
webReq.Headers.Add("Authorization: OAuth " + token);
webReq.Method = "PROPFIND";
// Adding data in body request.
string inputData = #"<D:propfind xmlns:D=""DAV:""><D:prop><quota-available-bytes/></D:prop></D:propfind>";
byte[] buffer = new ASCIIEncoding().GetBytes(inputData);
webReq.ContentType = "text/xml; encoding='utf-8";
webReq.ContentLength = buffer.Length;
try
{
HttpWebResponse resp = (HttpWebResponse)webReq.GetResponse();
StreamReader sr = new StreamReader(resp.GetResponseStream());
string dinfo = sr.ReadToEnd();
return dinfo;
}
}
I don't get any response, maybe i can use another method? What should i do?
Thanks!
quota-available-bytes should use same namespace "D"
Here's my code for Request and Response.
System.IO.MemoryStream xmlStream = null;
HttpWebRequest HttpReq = (HttpWebRequest)WebRequest.Create(url);
xmlStream = new System.IO.MemoryStream(System.Text.Encoding.UTF8.GetBytes(format));
byte[] buf2 = xmlStream.ToArray();
System.Text.UTF8Encoding UTF8Enc = new System.Text.UTF8Encoding();
string s = UTF8Enc.GetString(buf2);
string sPost = "XMLData=" + System.Web.HttpUtility.UrlDecode(s);
byte[] bPostData = UTF8Enc.GetBytes(sPost);
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.ContentType = "application/x-www-form-urlencoded";
HttpReq.Timeout = 30000;
request.Method = "POST";
request.KeepAlive = true;
using (Stream requestStream = request.GetRequestStream())
{
requestStream.Write(bPostData, 0, bPostData.Length);
requestStream.Close();
}
string responseString = "";
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
using (StreamReader sr = new StreamReader(response.GetResponseStream()))
{
responseString = sr.ReadToEnd();
}
No part of this code crashes. The "format" string is the one with XML in it. By the end when you try to see what's in the responseString, it's an empty string. I am supposed to see the XML sent back to me from the URL. Is there something missing in this code?
I would recommend a simplification of this messy code:
using (var client = new WebClient())
{
var values = new NameValueCollection
{
{ "XMLData", format }
};
byte[] resultBuffer = client.UploadValues(url, values);
string result = Encoding.UTF8.GetString(resultBuffer);
}
and if you wanted to upload the XML directly in the POST body you shouldn't be using application/x-www-form-urlencoded as content type. You probably should specify the correct content type, like this:
using (var client = new WebClient())
{
client.Headers[HttpRequestHeader.ContentType] = "text/xml";
var data = Encoding.UTF8.GetBytes(format);
byte[] resultBuffer = client.UploadData(url, data);
string result = Encoding.UTF8.GetString(resultBuffer);
}