When I do this:
config.Formatters.JsonFormatter.SerializerSettings.StringEscapeHandling = StringEscapeHandling.EscapeHtml;`
and then hit this endpoint:
[HttpGet]
public object TestApi()
{
return new {test = "<script>alert('o hai');</script>"};
}
it returns the unescaped string. All of the examples I've seen of the StringEscapeHandling are those manually using JsonConvert.SerializeObject.
Other JsonFormatter.SerializerSettings that I set work just fine except for that one. Is this not supported?
Related
I have a webapi controller code looks like:
[HttpPost]
public HttpResponseMessage DownloadForms(FormCriteria criteria)
{
string downloadData = new FormsToCsvHelper(Umbraco, criteria).GetCsv();
return Request.CreateResponse(HttpStatusCode.OK, downloadData);
}
If i look at the data returned in debugger just before sending it back it looks like:
Created Date,IP,Form Name,Email address,Message,Full Name
31/05/2019 10:43:08,127.0.0.1,Contact form - test,test12#hotmail.com,test,Ismail Mayat
If I copy and paste it into file and save as csv it looks fine in excel.
However the data i actually get back looks like:
"Created Date,IP,Form Name,Email address,Message,Full Name\r\n31/05/2019 10:43:08,127.0.0.1,Contact form - test,test12#hotmail.com,test,Ismail Mayat"
The whole record set it wrapped in quote and the line feed is seen as a literal so when opening file in excel its all on one line.
There is a DelegatingHandler that fire but that is for a specific url request so for this request it does not do anything.
Anyone any ideas whats going on?
WebAPI will serialize the value as JSON by default, so that's why your value is enclosed in double quotes.
To get around this, you can use the StringContent class:
return new HttpResponseMessage(statusCode) {
Content = new StringContent(downloadData, Encoding.UTF8, "text/csv")
};
I am facing a weird problem. In my Azure mobile app, I added a plain vanilla webapi controller with standard http verbs get, put etc. Now on my localhost everything is working fine. but when I deploy this to my azurewebsite. and call using Post man. the PUT request gets mapped to GET code. I tested using Postman, fiddler.
I am sure I am missing sth, but couldn't figure it out, checked the route, tried multiple options, but just couldn't figure out. Same is true with DELETE and POST. below is the sample code
[MobileAppController]
public class TestController : BaseController
{
// GET: api/Test
public IEnumerable<string> Get()
{
return new string[] { "value1", "value2" };
}
// GET: api/Test/5
public string Get(int id)
{
return "value";
}
// POST: api/Test
[Route("api/test")]
public async Task<string> Post([FromBody]string value)
{
await Task.Delay(100);
return "post: " + value;
}
// PUT: api/Test/5
[Route("api/test/{id}")]
public async Task<string> Put(int id, [FromBody]string value)
{
await Task.Delay(100);
return "put: " + value;
}
// DELETE: api/Test/5
[Route("api/test/{id}")]
public async Task<string> Delete(int id)
{
await Task.Delay(100);
return "delete: " + id;
}
You are mixing routing via WebAPI and routing via Mobile Apps, and they are conflicting. Pick one. For this application, I'd suggest removing the MobileAppController attribute and just going with the WebAPI routing.
Make sure you are making request via SSL i.e. your url should be starting from https.
when I was using Postman, my url was starting with "http" and any POST/PUT/DELETE request gets mapped to GET. and if I change it to "https" everything just works as expected.
I have a Web Api service that retrieves data from another service, which returns Json. I don't want to do anything to the response, I just want to return it directly to the client.
Since the response is a string, if I simply return the response, it contains escape characters and messy formatting. If I convert the response in to an object, the WebApi will use Json.Net to automatically format the response correctly.
public IHttpActionResult GetServices()
{
var data = _dataService.Get(); //retrieves data from a service
var result = JsonConvert.DeserializeObject(data); //convert to object
return Ok(result);
}
What I would like is to either A: Be able to return the exact string response from the service, without any of the escape characters and with the proper formatting, or B: Set a global settings that will automatically Deserialize the response so that the Web Api can handle it the way I am doing it already.
On Startup I am setting some values that describe how formatting should be handled, but apparently these aren't correct for what im trying to do.
HttpConfiguration configuration = new HttpConfiguration();
var settings = configuration.Formatters.JsonFormatter.SerializerSettings;
settings.Formatting = Formatting.Indented;
settings.ContractResolver = new DefaultContractResolver();
Do I need to create a custom ContractResolver or something? Is there one that already handles this for me?
Thanks
If you want to just pass through the json (Option A), you can do this
public IHttpActionResult GetServices() {
var json = _dataService.Get(); //retrieves data from a service
HttpContent content = new System.Net.Http.StringContent(json, Encoding.UTF8, "application/json");
var response = Request.CreateResponse(HttpStatusCode.OK);
response.Content = content;
return ResponseMessage(response);
}
I have an ASP.Net Web API project. In my controller is this simple 'boiler plate' API method:
using System.Web.Http;
public class DataController : ApiController
{
private static Random _Random = new Random();
[Route("api/getrandomdoubles/{count:int}")]
[AcceptVerbs("GET", "POST")]
public double[] GetRandomDoubles(int count)
{
var doubles = new double[count];
for (var i = 0; i < count; i++)
{
doubles[i] = _Random.NextDouble();
}
return doubles;
}
}
(N.B. I've cut out the other methods.)
If I call this in the browser thus http://localhost:1165/api/GetRandomDoubles/2 I get XML returned:
<ArrayOfdouble xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
<double>0.3777879822895806</double>
<double>0.46401416811347668</double>
</ArrayOfdouble>
And if I call it from JavaScript thus:
d3.json('api/getrandomdoubles/2', function (error, data) {
//Do stuff
});
I get back JSON [0.6679551008473873,0.9205140638726363].
What is deciding when my controller API method returns XML and when it returns JSON? I'm guessing it is decided based on the HTTP verb, i.e. PUT or GET but I cannot see where that is specified. How would I control the return type myself?
========== EDIT ==========
I have just realised that this is browser specific. Calling http://localhost:1165/api/GetRandomDoubles/2 in IE returns JSON, calling it in Chrome returns XML.
It is called as Content Negotiation in Web API.
First, the pipeline gets the IContentNegotiator service from the HttpConfiguration object. It also gets the list of media formatters from the HttpConfiguration.Formatters collection.
Next, the pipeline calls IContentNegotiatior.Negotiate, passing in:
The type of object to serialize
The collection of media formatters
The HTTP request
The Negotiate method returns two pieces of information:
Which formatter to use
The media type for the response
If no formatter is found, the Negotiate method returns null, and the client recevies HTTP error 406 (Not Acceptable).
I'm attempting to use an asp.net web api application to handle batched SendGrid events and I've run into a stumbling block due to the way SendGrid handles the content type header of the post it sends.
From their documentation:
Batched event POSTs have a content-type header of application/json,
and contain exactly one JSON string per line, with each line
representing one event. Please note that currently the POST headers
define this post as application/json, though it’s not; each line is a
valid JSON string, but the overall POST body is not.
So, given a controller:
public class SendGridController : ApiController
{
// POST api/values
public void Post([FromBody]string value)
{
// do something with value
}
}
Making a post to it as SendGrid does will result in "value" being null.
string URI = "http://localhost:3018/api/sendgrid/";
string myParameters =
#"={""email"":""foo#bar.com"",""timestamp"":1322000095,""user_id"":""6"",""event"":""bounced""}
{""email"":""foo#bar.com"",""timestamp"":1322000096,""user_id"":""9"",""event"":""bounced""}";
using (var wc = new System.Net.WebClient())
{
wc.Headers[System.Net.HttpRequestHeader.ContentType] = "application/json"; // I work fine if "application/x-www-form-urlencoded" is used.
wc.UploadString(URI, myParameters);
}
If I change the content type in my client example to "application/x-www-form-urlencoded", everything works as expected.
Is there an easy way for me to override this convention such that I can handle the badly formed "json" that sendgrid provides as a string in my controller method?
Ok, I finally figured it out. The trick was to remove the "value" param and work with the request object directly.
So something like:
public class SendGridController : ApiController
{
// POST api/values
public void Post()
{
var value = Request.Content.ReadAsStringAsync().Result;
// do something with value
}
}