65729

How to ensure that ServiceStack always returns JSON?

We have decided to only allow requests with a Content-Type header "application/json". So, whenever we receive a request with an alternative or missing Content-Type header, we throw an HttpError. This should return a 400 response containing a JSON ResponseStatus body with relevant info. However, if a Content-Type text/plain is sent, we throw an HttpError, but the response's Content-Type is text/plain and content-length: 0. I expected ServiceStack's ResponseStatus to be returned. The ResponseStatus is returned fine if I add an Accept application/json header to the request. I executed the request using Postman. Fiddler4 screen shot: <img src=https://www.e-learn.cn/content/wangluowenzhang/"https://i.stack.imgur.com/SoZIE.png" alt="">

I am aware that Postman adds the Accept / header. So my question is: How can I ensure that a thrown HttpError always return the ResponseStatus as JSON, no matter the request's Accept header?

The SetConfig:

SetConfig(new HostConfig { EnableFeatures = Feature.All.Remove( Feature.Html | Feature.Csv | Feature.Jsv | Feature.Xml | Feature.Markdown | Feature.Razor | Feature.Soap | Feature.Soap11 | Feature.Soap12 | Feature.PredefinedRoutes), DebugMode = false, DefaultContentType = MimeTypes.Json });

As I understand it, the DefaultContentType is only used whenever there isn't an Accept header in the request.

The PreRequestFilter:

PreRequestFilters.Add((request, response) => { if (request.Verb.Equals("OPTIONS")) response.EndRequest(); if (request.GetHeader("Content-Type") == null || !request.GetHeader("Content-Type").Equals(MimeTypes.Json)) throw new HttpError((int)HttpStatusCode.BadRequest, "Bad request", "Expected a Content-Type header with an application/json value but found none. See http://docsdomain.com/ for any required headers."); });

Answer1:

The HTTP Accept header is what the client uses to indicate what Response Type should be returned but you can override this to always return JSON by adding a Global Request Filter and explicitly setting the ResponseContentType, e.g:

GlobalRequestFilters.Add((req,res,dto) => req.ResponseContentType = MimeTypes.Json);

If the Accept Header doesn't specify a specific Response Type it will default to using the PreferredContentTypes which you can change by:

SetConfig(new HostConfig { PreferredContentTypes = new []{ MimeTypes.Json }.ToList(), });

Recommend

  • How to use Linq to Twitter inside a web service?
  • ServiceStack.DataAnnotations missing attributes definitions?
  • Turn Off ServiceStack Logging
  • Uber API doesn't allow request from localhost
  • Why Postman and Fiddler never generate preflight request
  • Can Delphi XE4 support iOS 4.x?
  • CORS issue with Vue.js
  • Retina 4 2x is never used for iPhone 5 simulator in Xcode 6.2 image asset
  • strptime in Javascript
  • Substitute partial line in vim using only substitute command
  • Upload file to Google Cloud Storage using AngularJS multipart form data
  • Servicestack client compression fails with generic lists
  • Is it safe to accept URL parameters for populating the `url_for` method?
  • Initialization section of the package
  • Possible to get the line number of the currently executing sproc in SQL Server?
  • How to set an entity field that does not exist on the table but does exists in the raw SQL as an ali
  • Meteor.. accounts- password— Create account on client without login
  • Thread synchronization with syncwarp
  • How can I run DataNucleus Bytecode Enhancer from SBT?
  • Jquery Knockout: ko.computed() vs classic function?
  • OSX - always hide certain files
  • Application level floating views with navigation in Android
  • Ember.js model to be organised as a tree structure
  • AndEngine Applying Transparancy to AndEngine View
  • How does document.ready work with angular element directives?
  • Using a canvas object in a thread to do simple animations - Java
  • Tamper-proof configuration files in .NET?
  • Caching attributes in superclass
  • Is it possible to access block's scope in method?
  • Avoid links criss cross / overlap in d3.js using force layout
  • Paperclip, set path outside of rails root folder
  • SignalR .NET Client Invoke throws an exception
  • Sony Xperia Z Tablet not found by adb
  • How to recover from a Spring Social ExpiredAuthorizationException
  • WinForms: two way TextBox problem
  • ActionScript 2 vs ActionScript 3 performance
  • How can I estimate amount of memory left with calling System.gc()?
  • WPF Applying a trigger on binding failure
  • Hits per day in Google Big Query
  • how does django model after text[] in postgresql [duplicate]