Parsing AWS SNS notification in .net core 1.0 - json

I have a VisualStudio17 serverless application project and am using .net core Web Api.
I want to confirm my SNS subscription, but I have a problem that AWS sends the POST request with header content-type set to text/plain; charset=UTF-8 while body is JSON.
Here's an example request from their documentation:
POST / HTTP/1.1
x-amz-sns-message-type: Notification
x-amz-sns-message-id: da41e39f-ea4d-435a-b922-c6aae3915ebe
x-amz-sns-topic-arn: arn:aws:sns:us-west-2:123456789012:MyTopic
x-amz-sns-subscription-arn: arn:aws:sns:us-west-2:123456789012:MyTopic:2bcfbf39-05c3-41de-beaa-fcfcc21c8f55
Content-Length: 761
Content-Type: text/plain; charset=UTF-8
Host: ec2-50-17-44-49.compute-1.amazonaws.com
Connection: Keep-Alive
User-Agent: Amazon Simple Notification Service Agent
{
"Type" : "Notification",
"MessageId" : "da41e39f-ea4d-435a-b922-c6aae3915ebe",
"TopicArn" : "arn:aws:sns:us-west-2:123456789012:MyTopic",
"Subject" : "test",
"Message" : "test message",
"Timestamp" : "2012-04-25T21:49:25.719Z",
"SignatureVersion" : "1",
"Signature" : "EXAMPLElDMXvB8r9R83tGoNn0ecwd5UjllzsvSvbItzfaMpN2nk5HVSw7XnOn/49IkxDKz8YrlH2qJXj2iZB0Zo2O71c4qQk1fMUDi3LGpij7RCW7AW9vYYsSqIKRnFS94ilu7NFhUzLiieYr4BKHpdTmdD6c0esKEYBpabxDSc=",
"SigningCertURL" : "https://sns.us-west-2.amazonaws.com/SimpleNotificationService-f3ecfb7224c7233fe7bb5f59f96de52f.pem",
"UnsubscribeURL" : "https://sns.us-west-2.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:us-west-2:123456789012:MyTopic:2bcfbf39-05c3-41de-beaa-fcfcc21c8f55"
}
Content-type: text, body JSON. This makes it parsing quite difficult, and a simple
public void Post([FromBody] string t) // or dynamic t for the matter
doesn't work and throws the Request was short circuited at action filter 'Microsoft.AspNetCore.Mvc.ModelBinding.UnsupportedContentTypeFilter'. exception.
Am I missing something? Why are they doing this and how do I work with this?

I made it work like I described in this answer, by adding text/plain to formats that JsonInputFormatter should format.
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc(config =>
{
foreach (var formatter in config.InputFormatters)
{
if (formatter.GetType() == typeof(JsonInputFormatter))
((JsonInputFormatter)formatter).SupportedMediaTypes.Add(
MediaTypeHeaderValue.Parse("text/plain"));
}
});
...
}

Related

HTTP 406 not acceptable response header fiddler

I am using fiddler 4 as a frond-end service for elasticsearch.
I'm trying to store a document into index using API following this.
Here's my sample json as request body:
{
"fruit": "Apple",
"size": "Large",
"color": "Red"
}
API : http://localhost:9200/food/fruit
method :POST HTTP/1.1
Here's the response:
As mentioned in their doc., "Starting from Elasticsearch 6.0, all REST requests that include a body must also provide the correct content-type for that body." adding content-type: application/json in the request solved the issue.

WCF : Generate JSON not works

I'm using DevExpress, XAF, and XPO for my application. I need to expose my data from a webservice.
ASP.NET Web API V2 is not compatible with XPO objects... (If you found how to... I will take it!).
The DevExpress wizard can help me to generate a WCF Web Service project, where
MyContext inherits from XpoContext
MyService inherits from XpoDataServiceV3 (and the class have an attribute : [JSONPSupportBehavior])
I would get a list of my XPO Objects, for that, I wrote the next code
[WebGet]
public IQueryable<MyType> Get()
{
return new XPQuery<MyType>(new UnitOfWork());
}
I have found various properties on WebGet attribute : RequestFormat, ResponseFormat, BodyStyle, UrlTemplate. On Format properties, I have the choise between WebMessageFormat.Json and WebMessageFormat.Xml. Logically, I type WebMessageFormat.Json.
When I go on my favorite webbrowser or fiddler, I do this request:
GET http://localhost:51555/MyService.svc/Get HTTP/1.1
User-Agent: Fiddler
Host: localhost:51555
Content-Type: application/json
But this not works... The response is :
HTTP/1.1 200 OK
Cache-Control: no-cache
Content-Length: 24250
Content-Type: application/atom+xml;type=feed;charset=utf-8
Server: Microsoft-IIS/10.0
...
And content was wrote in XML.
We are okay, I have configure my query with format properties... :
[WebGet(RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
I've found ! On your WCF service global class, wrote the following code :
HttpContext.Current.Request.Headers.Add("Accept", "application/json;");

grails controller - POST json request

I have very simple controller with the following method:
def createNewWidgetVersion() {
println request.JSON
render status: OK
}
I'm sending the following request:
POST /CMSAdmin/widgetVersion/createNewWidgetVersion HTTP/1.1 Host:
localhost:8080
Content-Type: application/json
Cache-Control: no-cache
{ "htmlText":"33", "javaScript":
"document.getElementById('ffsdfdsfsfsfsd')", "comments":"SUCCESS",
"widgetId": "1", "type": "LIVE" }
and when debugging, IDE shows that request.JSON is empty. Controller doesn't extend RestfullController but I think it doesn't have to in this particular siutation. Could you please give a hint what I'm doing wrong? Spent few hours dealing with this. Thanks!
UPD1
I added the following to UrlMappings.groovy:
"/widgetVersion/"(controller: "widgetVersion", parseRequest:true){
action = [POST:'createNewWidgetVersion']
}
is there any way to avoid this? Thanks!

WebAPI: A callback parameter was not provided in the request URI

I am executing a post method in my API using fiddler I get error "A callback parameter was not provided in the request URI.". However, this works for get method.
I have seen several answers to this question, and as per the error I need to specify a callback parameter. However, I'm not sure how to do this using fiddler.
In response to one of those answers from Can I make a jQuery JSONP request without adding the '?callback=' parameter in URL? . I've tried the following in fiddler and I get the same error..
url: http://velopoint-api.localhost.dev/api/v1/tasks?callback=foo
header:
User-Agent: Fiddler
Host: velopoint-api.localhost.dev
ContentType: application/json; charset=utf-8
Authorization: basic "UNQUOTED"
Content-Length: 47
jsonp: true
jsonpCallback: jsonCallback
dataType: jsonp
request body
{ "Title":"New Task", "DueDate":"20-jul-2014" }
Startup
public static void Register(HttpConfiguration config)
{
config.MapHttpAttributeRoutes();
// Uncomment the following line of code to enable query support for actions with an IQueryable or IQueryable<T> return type.
// To avoid processing unexpected or malicious queries, use the validation settings on QueryableAttribute to validate incoming queries.
// For more information, visit http://go.microsoft.com/fwlink/?LinkId=279712.
// Change Formater to use CamelCasePropertyNamesContractResolver
var jsonFormatter = config.Formatters.OfType<JsonMediaTypeFormatter>().FirstOrDefault();
jsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
/* Support JsonP */
//register JSONP media type formatter
config.Formatters.Insert(0, new JsonpMediaTypeFormatter(jsonFormatter));
config.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Serialize;
config.Formatters.JsonFormatter.SerializerSettings.PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.Objects;
...
}
After playing around a little, I've finally figured it wasn't actually routing to the post method.
My header is now
User-Agent: Fiddler
Host: velopoint-api.localhost.dev
Authorization: basic UNQUOTED
Content-Length: 224
Content-Type: application/json
I fixed the problem by specifying Route attribute to my Post method and passing an empty string to the pattern parameter, both on the Get and the Post (as I already have the RoutePrefix attribute specified on the class.
[RoutePrefix("api/v1/tasks")]
[VeloPointAuthorise(perUser: true)]
public class TaskController : BaseApiController
{
[HttpGet]
[Route(template:"", Name = "TaskRoute")]
public HttpResponseMessage Get(int page = 0)
{
....
}
[HttpPost]
[Route(template:"")]
public HttpResponseMessage Post([FromBody] OrganiserTaskModel model)
{
....
}

dojo/request/xhr calling Perl Web Service on different domain -getting scripting errors

I understand Dojo's XHR mechanism supports CORS but sets the X-Requested-With by default. I just have to set the headers = {"X-Requested-With":null }
So I am using dojo/request/xhr to call a Perl Web Service (Catalyst Framework)
xhr.get(url, {
handleAs: "json",
headers: {"X-Requested-With": null}
I'm using Fiddler and this is the JSON string:
{
"data" : [
{
"structure" : [
{
"name" : "State"
}
],
"dataSource" : [
{
"State" : "CA",
"Id" : 1
}
]
}
]
}
Fiddler returns an HTTP Result of 200 but I'm getting an error in dojo.then{}
"Unable to load http://Server:3000/state/ status: 0"
I also tried using dojo/request/script to call a Perl Web Service (Catalyst Framework)
script.get(url, {
jsonp: "callback"
}).then(...
But I get scripting error:
JavaScript critical error at line 2, column 11 in http://Server:3000/state/?callback=dojo_request_script_callbacks.dojo_request_script0\n\nSCRIPT1004: Expected ';'
It highlights the ":" after "data". I don't believe this ill-formed json string because my MVC controller method can call the Perl Server using WebClient's DownloadStringTaskAsync and return the value as a ContentString.
Any ideas??
If you're using CORS, you have to do more than just setting an X-Requested-With header. You also have to make sure the server sends the right headers, it had to send the Access-Control-Allow-Origin header and probably also the Access-Control-Request-Header header, for example:
Access-Control-Allow-Origin: *
Access-Control-Request-Header: x-requested-with
If you're using JSONP, your webservice must support JSONP, which means it's wrapping the entire result in a callback function.