ASP.NET
[HttpPost]
[Route("apitest")]
public string apitest([FromBody]string str)
{
Console.Writeline(str); // str is always null
return null;
}
Angular 2:
var creds = "str='testst'" ;
var headers = new Headers();
headers.append('Content-Type', 'application/x-www-form-urlencoded');
http.post('http://localhost:18937/apitest', creds, {
headers: headers
})
.map(res => res.json())
.subscribe(
(res2) => {
console.log('subsribe %o', res2)
}
);
I also tried creds = {"str":"test"}; without headers JSON.stringify() etc. without success. How do I Post data to ASP.NET?
var creds = {
str: 'testst'
};
$http.post('http://localhost:18937/apitest', JSON.stringify(creds));
No changes in Web API controller and it should work.
This is probably an issue with the way that ASP.NET and MVC handle data POSTS.
[HttpPost]
public ActionResult Index(int? id)
{
Stream req = Request.InputStream;
req.Seek(0, System.IO.SeekOrigin.Begin);
string json = new StreamReader(req).ReadToEnd();
InputClass input = null;
try
{
// assuming JSON.net/Newtonsoft library from http://json.codeplex.com/
input = JsonConvert.DeserializeObject<InputClass>(json)
}
catch (Exception ex)
{
// Try and handle malformed POST body
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
//do stuff
}
You can refer to my answer here and the referenced links as to a potential cause of the issue. There are quite a few server side web frameworks that inappropriately handle data POSTS and by default doesn't add the data to your request object.
You shouldn't [have to] try and change the behavior of your angular post, and modify headers to pretend your data post is a form post.
Related
I have the snippet in C# and was looking for some advice converting it to PHP.
Basically, what is happening here, I am building somewhat of a middleware site.
A user submits a form named "Basket" and creates a POST request with XML body to this file, which will parse it, create a new URL with parameters which will afterwards be sent to Shopify cart.
Any help is appreciated.
public class DefaultController : ApiController
{
public IHttpActionResult Post()
{
var query = "";
var domain = "https://shop.shopify.io/cart";
try
{
var content = Request.Content.ReadAsFormDataAsync().Result;
var document = XDocument.Parse(content["basket"]);
if (document.Root != null)
{
var products = document.Root.Elements().Select(x => x.Element("productid").Value + ":" + x.Element("amount").Value);
query = string.Join(",", products);
}
}
catch
{ }
if (string.IsNullOrEmpty(query))
return Redirect(domain);
return Redirect($"{domain}?query={query}");
}
}
```
I have a requirement where I have been posting data to a web API as a json string in a POST request and the post method retrieves the data from the body. This works perfectly for most data, but it does not work when I include a long dash(—) as part of the data in any fields.
I have a Email class with some string fields and I am passing it to the API to save in the database.
Here is how I am implementing the call:
public string PostNewEmailRecord(string APIEndpoint, CampaignWave Email)
{
string StrEmailId = string.Empty;
_endpoint = APIEndpoint;
try
{
string strData = JsonConvert.SerializeObject(Email);
_client.Headers.Add(HttpRequestHeader.ContentType, "application/json");
_client.UploadString(APIEndpoint, _requestType, strData);
}
catch (Exception ex)
{
}
return StrEmailId;
}
And here is the post method of Web API:
public void Post([FromBody]CampaignWave email)
{
try
{
using (var transaction = new TransactionScope())
{
CampaignWaveRepository cr = new CampaignWaveRepository();
object objReturnValue = cr.Insert(email);
transaction.Complete();
}
}
catch (Exception ex)
{
}
finally
{
}
}
When I include a dash the API post method receives a null value as email.
Please help me how I can successfully pass the '—' without any issue. Thanks in advance.
Based on comments it could be caused by encoding:
client.Encoding = Encoding.UTF8
first its something that happening in webapi 2.2 and not in the old one
https://devblogs.microsoft.com/aspnet/asp-net-core-2-1-web-apis/
I get from webapi response
{
"ProductValue": [
"The input was not valid."
]
}
how i cancel this response and just get false in
ModelState.IsValid
i need to return more fields to response
and this response is not good for me
for those who have hard trouble to understand in dubug i dont enter to
this function at all,because web api built in mechanism
return his response instend of mine
{code=9}
public MyResponse Start(Request req)
{
if (ModelState.IsValid)
{
return new MyResponse(){code=0} ;
}
return new MyResponse(){code=9} ;
}
Not absolutely sure what you are trying to achieve but if you want to send your own custom error response then you can probably do something like below (Hypothetically)
Product p = GetProduct(productvalue);
if (p == null)
{
HttpError err = new HttpError($"Product with productvalue {productvalue} not found");
return Request.CreateResponse(HttpStatusCode.NotFound, err);
}
else
{
return Request.CreateResponse(HttpStatusCode.OK, p);
}
services.AddMvc()
.ConfigureApiBehaviorOptions(options =>
{
options.SuppressModelStateInvalidFilter = true;
});
thanks to Kirk Larkin
I am implementing webhook test code and I am running into a problem.
After I POST a sample notification to my webhook listener the Params are not in the request:
Request.Params["bt_signature"]
Request.Params["bt_payload"]
So the listener fails.
Below is both my Post Webhook code and Listener code; I'm not sure if I'm using gateway.WebhookTesting.SampleNotification correctly.
POST Test Webhook
private async Task PostTestNotification()
{
try
{
using (var client = new HttpClient())
{
client.BaseAddress = new Uri("http://localhost:50709/");
var gateway = config.GetGateway();
// Create sample notification
Dictionary<String, String> sampleNotification = gateway.WebhookTesting.SampleNotification(
WebhookKind.SUBSCRIPTION_CHARGED_SUCCESSFULLY, "sub_id_1234"
);
// Convert sample notification to JSON
string payloadJson = JsonConvert.SerializeObject(sampleNotification);
// Create StringContent of json sample notificaiton
var data = new StringContent(payloadJson);
// data looks like this when debugging { "bt_payload":"PG5vdGlmaWNhdGlvbj48dGltZXN0YW1wIHR5cGU9ImRhdGV0aW1lIj4yMDE2LTA1LTI3IDEzOjM2OjEwWjwvdGltZXN0YW1wPjxraW5kPnN1YnNjcmlwdGlvbl9jaGFyZ2VkX3N1Y2Nlc3NmdWxseTwva2luZD48c3ViamVjdD48c3Vic2NyaXB0aW9uPjxpZD5zdWJfaWRfMTIzNDwvaWQ+PHRyYW5zYWN0aW9ucz48dHJhbnNhY3Rpb24+PGlkPnN1Yl9pZF8xMjM0PC9pZD48YW1vdW50PjQ5Ljk5PC9hbW91bnQ+PHN0YXR1cz5zdWJtaXR0ZWRfZm9yX3NldHRsZW1lbnQ8L3N0YXR1cz48ZGlzYnVyc2VtZW50LWRldGFpbHM+PGRpc2J1cnNlbWVudC1kYXRlIHR5cGU9ImRhdGUiPjIwMTMtMDctMDk8L2Rpc2J1cnNlbWVudC1kYXRlPjwvZGlzYnVyc2VtZW50LWRldGFpbHM+PGJpbGxpbmc+PC9iaWxsaW5nPjxjcmVkaXQtY2FyZD48L2NyZWRpdC1jYXJkPjxjdXN0b21lcj48L2N1c3RvbWVyPjxkZXNjcmlwdG9yPjwvZGVzY3JpcHRvcj48c2hpcHBpbmc+PC9zaGlwcGluZz48c3Vic2NyaXB0aW9uPjwvc3Vic2NyaXB0aW9uPjwvdHJhbnNhY3Rpb24+PC90cmFuc2FjdGlvbnM+PGFkZF9vbnMgdHlwZT0iYXJyYXkiPjwvYWRkX29ucz48ZGlzY291bnRzIHR5cGU9ImFycmF5Ij48L2Rpc2NvdW50cz48L3N1YnNjcmlwdGlvbj48L3N1YmplY3Q+PC9ub3RpZmljYXRpb24+\n","bt_signature":"69r68j6hnzjpnq4j|508a7b4b3bbbe15c241c742331acfc5bacf37c54"}
// POST
HttpResponseMessage response = await client.PostAsync("webhooks/accept", data);
// RESPONSE
if (response.IsSuccessStatusCode == true)
{
// SUCCESS CONTENT
string resultJSON = await response.Content.ReadAsStringAsync();
}
else
{
// FAIL CONTENT
dynamic problem = await response.Content.ReadAsStringAsync();
}
}
}
catch (Exception ex)
{
//
Console.WriteLine("Exception: " + ex.Message);
}
}
Webhook LISTENER
// webhooks/accept endpoint
public async Task<ActionResult> accept()
{
try
{
var gateway = config.GetGateway();
if (Request.HttpMethod == "POST")
{
var bt_signature = Request.Params["bt_signature"]; <<<<<<< ALWAYS EMPTY >>>>>>>>>
var bt_payload = Request.Params["bt_payload"]; <<<<<<< ALWAYS EMPTY >>>>>>>>>
WebhookNotification webhookNotification = gateway.WebhookNotification.Parse(
Request.Params["bt_signature"],
Request.Params["bt_payload"]
); <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< EXCEPTION WHEN HIT - Value cannot be null, Parameter name: Input >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
// ACTION Webhook
if (webhookNotification.Kind == WebhookKind.SUBSCRIPTION_CANCELED)
{
IsActive = false;
await Logger.LogInsight("", "WEBHOOK: SUBSCRIPTION_CANCELED " + webhookNotification.Subscription.Id );
}
else if (webhookNotification.Kind == WebhookKind.SUBSCRIPTION_CHARGED_SUCCESSFULLY)
{
IsActive = true;
await Logger.LogInsight("", "WEBHOOK: SUBSCRIPTION_CHARGED_SUCCESSFULLY " + webhookNotification.Subscription.Id);
}
// code ommitted for brevity, similar to above checking all 'kind' values
}
}
}
Why are the Braintree Request Params empty?
The problem was in the Webhook endpoint, the Braintree sample code is incorrect, it implies using MVC but developers need to use the Web Api for this, and the sample code will not work.
To get this working I left the Sample Notification POST above unchanged and created a new Webhook listener :
First create a class to receive the two braintree strings from the POST:
public class bt
{
public string bt_payload { get; set; }
public string bt_signature { get; set; }
}
And now create an empty Web Api 2 Controller:
[HttpPost]
[Route("api/webhooks/accept")]
public async Task<IHttpActionResult> accept(bt bt_lot)
{
var gateway = config.GetGateway();
WebhookNotification webhookNotification = gateway.WebhookNotification.Parse(
bt_lot.bt_signature,
bt_lot.bt_payload
);
if (webhookNotification.Kind == WebhookKind.SUBSCRIPTION_CANCELED)
{
// take your action here...
}
Im posting all my experiences with Braintree here on SO as there isn't a great deal of help here and I hope it helps others.
I have to say the Braintree Help staff are excellent and always answer questions with very detailed answers that 95% of the time resolved any issues I had, but this issue had me scratching my head as their example didn't work and the help staff assumed like me that the code should work.
We're using OpenWeb js libraries on the frontend, and they have a need for the .NET middle tier to send them a specific HTTP header status code when certain types of errors occur. I tried to achieve that by doing this:
public ActionResult TestError(string id) // id = error code
{
Request.Headers.Add("Status Code", id);
Response.AddHeader("Status Code", id);
var error = new Error();
error.ErrorID = 123;
error.Level = 2;
error.Message = "You broke the Internet!";
return Json(error, JsonRequestBehavior.AllowGet);
}
It kind of halfway worked. See screenshot:
http status code http://zerogravpro.com/temp/pic.png
Notice I achieved the Status Code of 400 in the Response Header, but I really need the 400 in the Request Header. Instead, I get "200 OK". How can I achieve this?
My URL structure for making the call is simple: /Main/TestError/400
There is extended discussion at What is the proper way to send an HTTP 404 response from an ASP.NET MVC action?
What you want to do is set Response.StatusCode instead of adding a Header.
public ActionResult TestError(string id) // id = error code
{
Response.StatusCode = 400; // Replace .AddHeader
var error = new Error(); // Create class Error() w/ prop
error.ErrorID = 123;
error.Level = 2;
error.Message = "You broke the Internet!";
return Json(error, JsonRequestBehavior.AllowGet);
}
If all you want to return is the error code, you could do the following:
public ActionResult TestError(string id) // id = error code
{
return new HttpStatusCodeResult(id, "You broke the Internet!");
}
Reference: MSDN article on Mvc.HttpStatusCodeResult.
Otherwise, if you want to return other information use
Response.StatusCode = id
instead of
Response.AddHeader("Status Code", id);
If you can't get your json result into your view, try to add this :
Response.TrySkipIisCustomErrors = true;
Before this :
Response.StatusCode = 400;
More details on this post : https://stackoverflow.com/a/37313866/9223103