for my WebAPI OData application, im trying to give my client (browser) the decision what format the data output should be. as $format is not implemented yet in WebAPI OData, im using Raghuramn's example here: https://gist.github.com/raghuramn/5556691
var queryParams = request.GetQueryNameValuePairs();
var dollarFormat = queryParams.Where(kvp => kvp.Key == "$format").Select(kvp => kvp.Value).FirstOrDefault();
if (dollarFormat != null)
{
request.Headers.Accept.Clear();
request.Headers.Accept.Add(MediaTypeWithQualityHeaderValue.Parse(dollarFormat));
// remove $format from the request.
request.Properties[HttpPropertyKeys.RequestQueryNameValuePairsKey] = queryParams.Where(kvp => kvp.Key != "$format");
}
This works for JSON ($format=application/json;odata=fullmetadata) and JSON light (format=application/json;odata=light) but so far not for xml.
if i add $format=application/XML to the querystring, it still outputs to json light. how do i force XML output?
EDIT:
even if i force xml in Fiddler by sending
Content-type: application/xml and
Accept: application/xml
with the request, the response simply lists:
Content-Type: application/json; odata=minimalmetadata; streaming=true; charset=utf-8
EDIT 2:
Accept: application/atom+xml does seem to output xml in the raw response. Unfortunately, "application/atom+xml" throws a FormatException in:
request.Headers.Accept.Add(MediaTypeWithQualityHeaderValue.Parse("application/atom+xml"));
setting the request ContentType instead of the AcceptHeader did the trick:
request.Content.Headers.ContentType = MediaTypeHeaderValue.Parse("application/atom+xml");
Thanks to a search on the keywords request.Headers.Accept.Add and MediaTypeWithQualityHeaderValue that were presented by this question, I found a CodeProject Article that actually presented the syntax to correctly add the Accept header and solve the same issue:
this.Request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/atom+xml"));
instead of MediaTypeWithQualityHeaderValue.Parse("application/atom+xml") which throws the FormatException.
Related
I just created a HTTP get request to get the content(All the Badges) from stack overflow for my console application as shown below :
public void getStackBadges()
{
var client = new HttpClient();
client.BaseAddress = new Uri("https://api.stackexchange.com/docs//badges?order=desc&sort=rank&site=stackoverflow");
var res = client.GetAsync(client.BaseAddress).Result;
Console.WriteLine(res);
}
Can anybody please tell if i want to get all the badges from stack overflow using this API what i need to do. I don't realy understand the format of result that i am getting on my Cmd prmt !
Output on Console:
StatusCode: 200, ReasonPhrase: 'OK', Version: 1.1, Content: System.Net.Http.StreamContent, Headers:
{
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST
Access-Control-Allow-Credentials: false
X-Content-Type-Options: nosniff
Cache-Control: private
Date: Thu, 28 Dec 2017 09:49:33 GMT
Content-Length: 880
Content-Encoding: gzip
Content-Type: application/json; charset=utf-8
}
You're querying the documentation of the API and you're most likely getting the page markup.
You should be querying: https://api.stackexchange.com/2.2/badges?order=desc&sort=rank&site=stackoverflow
The format of the output in above API method is JSON.
Few things to note in the output:
quota_max - Tells you how many requests can be made by you in a day.
quota_remaining - How many requests more you can make today.
has_more - If there is another page with badges.
To change the page you append a &page= parameter to the url.
So your query for page 2 would look like this:
https://api.stackexchange.com/2.2/badges?page=2&order=desc&sort=rank&site=stackoverflow
Edit:
As I said, the API I have linked is correct, your problem is the way you try to display the content of the response from the API.
.Result is not what you think it is. .Result returns Task<TResult> which is not the response from the API but the result of the request. That's why you have status code of the request, response type, etc etc.
Here's how to retrieve the response text. This is a sample, you'll need to do your own processing if you want to access different properties of the response objects. This is a separate question though and it's outside the scope of this one.
var response = client.GetAsync("https://api.stackexchange.com/2.2/badges?order=desc&sort=rank&site=stackoverflow").Result;
string res = "";
using (HttpContent content = response.Content)
{
Task<string> result = content.ReadAsStringAsync();
res = result.Result;
}
I have a C# / .NET WebApi endpoint tied to a number. When that number receives a text, it's forwarded to my API via webhook.
Sometimes (not all the time), I get an error in my debugger with the following:
Error - 12300
Invalid Content-Type
Twilio is unable to process the Content-Type of the provided URL.
Please see the Twilio Markup XML Documentation for more information on
valid Content-Types. You must return a Content-Type for all requests.
Requests without a Content-Type will appear in the App Monitor as a
502 Bad Gateway error.
In the response that triggered this, I see the following:
With the following headers:
Content-Type application/json; charset=utf-8
Pragma no-cache
Date Sat, 14 Jan 2017 02:57:45 GMT
X-AspNet-Version 4.0.30319
X-Powered-By ASP.NET
What might be causing this, and how do I address it?
After some research from TWIML MESSAGE: YOUR RESPONSE
this code seems to work
[HttpGet]
public HttpResponseMessage SmsAnswerCallBack(string id)
{
_smsAnswerCallBackCallIndex++;
var r = new SmsApiResult();
r.SetStatus(true, _smsSendCallIndex, _smsAnswerCallBackCallIndex);
r.DataList = _answers;
var res = Request.CreateResponse(HttpStatusCode.OK);
res.Content = new StringContent("<Response/>", Encoding.UTF8, "text/xml");
return res;
}
I too was sending a json response and getting this error. Using the answer by Frederic Torres got me on the right track. It looks like Twilio is looking for XML in TwiML format. But if you basically just return an empty "Response" element in text/xml format, that satisfies Twilio. So here is a simplified answer for anybody else that runs into this:
public ContentResult IncomingSMS(string To, string From, string Body)
{
//do stuff
//...
return Content("<Response/>", "text/xml");
}
public IEnumerable<Word> GetWords()
{
return db.Words.ToList();
}
I need this output in XML using webapi2; I already googled and try
var appXmlType = config.Formatters.XmlFormatter.SupportedMediaTypes.FirstOrDefault(t => t.MediaType == "text/xml");
config.Formatters.XmlFormatter.SupportedMediaTypes.Remove(appXmlType);
It returns data only in JSON.
Also I updated the package Microsoft.AspNetCore.Mvc.Formatters.Xml
How can I get it in XML?
Thanks in advance.
set both the HTTP Accept and Content-Type headers to "application/xml".
I set up an empty Web API project and issued a GET request with PostMan. Out of the box the Web API returned XML like
<ArrayOfstring xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
<string>value1</string>
<string>value2</string>
</ArrayOfstring>
for the default example controller. The trick is to set the Accept Header in the request.
Accept: text/xml (or application/xml)
Keep in mind that the stated line
config.Formatters.XmlFormatter.SupportedMediaTypes.Remove(appXmlType);
removes the media type. So it will disable XML output (and not enable it).
I'm using RestSharp to make a call to REST service. My call looks something like this:
var request = new RestRequest("/foo", Method.POST);
request.JsonSerializer.ContentType = "application/json; charset=utf-8";
request.AddJsonBody(new string[] { "param1", "param2" });
var response = this._client.Execute<Foo>(request);
For most other calls this works fine. I'm running into issues when the response is compressed. The headers in the response look (mostly) like this:
HTTP/1.1 200 OK
Uncompressed-Size: 35000
Content-Length: 3019
Content-Encoding: deflate
Content-Type: application/json
The issue is when I call this method with RestSharp I keep getting the error:
Error: Block length does not match with its complement.
I've tried setting the Accept-Encoding header in the request but it still produces the error. I also tried using a custom deserializer but the error is occurring before deserialization. From what I can tell, RestSharp should automatically handle deflation if the Content-Encoding header says deflate (which it does).
How can I get RestSharp to handle the deflation properly?
UPDATE
In the end I was able to have the service changed to look for an Accept-Encoding header in the request with a value of identity. If found, the service was changed to return the data uncompressed.
This is unfortunately not really a solution to the original issue but it does resolve the problem for me. If a better solution is posted I will try it.
According to this post, you should be able to handle it if you won't pass charset=utf-8 in content type.
Please refer to this:
RestSharp compress request while making rest call to server
Really struggling with something I hope people here can help with. I'm writing a RESTful API in Web API 2. Whenever I send a request to this service, the response is consistently being sent with a Content-Type of text/plain. Obviously this is no good, my response needs to be Content-Type of application/json. I've tried a few suggestions that I found from Google but I don't think I'm understanding the whole picture.
Is there something special I need to do in order to have my web service respond with application/json content? Note that I want this to work globally across the whole app, so I'm not after a way to modify a given response and set its content type - I want this to be a default behaviour for the whole web service: If a request contains an Accept header for application/json I want my web service to return that Content-Type instead of text/plain.
Edit to clarify:
My response contains an object called "responseData" that should be serialized into JSON and included in the body. I'm currently putting together my response like this:
HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.OK, responseData);
return response;
responseData is a POCO. This get's correctly serialized as JSON and returned in the response - the only missing part is the Content-Type which is incorrectly set to "text/plain". I could manually change this on every single response I compose, but I'm wanting to configure this on a global level.
OK, assuming that your responseData is a string, the Content-type header will be text/plain when you create the HttpResponseMessage. Doesn't matter what the contents of the string are, since no attempt is made to determine this.
The solution is to create the appropriate Content object for your message, initialized with the media type you're returning:
HttpResponseMessage response = new HttpResponseMessage()
{
Content = new StringContent(
responseData,
Encoding.UTF8,
"application/json"
)
};
There are other methods that amount to returning a particular object type and letting the API libraries serialize to JSON or XML for you as required. I prefer to let the framework do the work for me where possible, but this is how you'd achieve it with a string you've created yourself.
For a strict JSON-only result, remove the XML formatter from the WebAPI configuration and return your POCO.
In App_Start\WebApiConfig.cs, add the following to the WebApiConfig.Register method:
config.Formatters.Remove(config.Formatters.XmlFormatter);
And for your API:
public class MyObject
{
public bool result;
public string reason;
}
public class TestController : ApiController
{
public MyObject GetData()
{
MyObject result = new MyObject { result = "true", reason = "Testing POCO return" };
return result;
}
}
I ran this up and requested /api/Test from Chrome, which doesn't even mention application/json in the Accept header. Here are the response headers up until it hits Content-Type:
HTTP/1.1 200 OK
Cache-Control: no-cache
Pragma: no-cache
Content-Type: application/json; charset=utf-8
And the body:
{"result":true,"reason":"Testing POCO return"}
Since I disabled XML it defaulted to JSON.
Add the following to Global.asax file.
protected void Application_Start()
{
JsonSerializerSettings serializerSettings = new JsonSerializerSettings();
serializerSettings.Converters.Add(new IsoDateTimeConverter());
var jsonFormatter = new JsonNetFormatter(serializerSettings);
jsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));
GlobalConfiguration.Configuration.Formatters.Insert(0, jsonFormatter);
}
Another possible source of the issue described is that there may be an authorization redirect in play as was the case for us when one of the engineers thought to re-use user authentication for an api.
This means incoming requests were being redirected to a login page which was the text/html response that couldn't be parsed by ReadAsync<>. A silly mistake to be sure, but not an easy one to spot.
The solution in that case was to remove the user authentication and implement HMAC based authentication for the api.