postman - Asp.net core seems to ignore the Accept:"application/xml" header for my custom formatter -


the api i'm building returns json everywhere, need return xml custom formatter.

i created custom formatter (i didn't copy writeresponsebodyasync keep shorter)

public class xmloutputformatter : textoutputformatter {     public xmloutputformatter()     {         supportedmediatypes.add(mediatypeheadervalue.parse("application/xml"));         supportedencodings.add(encoding.utf8);         supportedencodings.add(encoding.unicode);     }      protected override bool canwritetype(type type)     {         return true; // tried doing force work on type,                       // don't think it's needed     }      public override bool canwriteresult(outputformattercanwritecontext context)     {         if (context == null)              throw new argumentnullexception(nameof(context));          return context.contenttype.tostring() == "application/xml";     } } 

it works when have

[produces("application/xml")] 

on controller method, when don't use , ask xml in postman using accept:application/xml header still returns json.

postman

i added formatter in startup.cs so:

services     .addmvc(options =>     {         options.outputformatters.add(new xmloutputformatter());     }); 

i know formatter works issue asp seems ignore accept header , returns json. know force return xml, prefer returning xml.

i know there default xml formatter, doesn't behave need to.

i'm using asp.net core 2.0 , visual studio professional 2017 15.3 preview 6

this answer bit hasty... cover enough answer question.

check content-type , accept

you need make sure content-type , accept headers in request set properly. in case (application/xml).

i have full example in answer. note use addmvccore (see next section below)

use addmvccore instead.

the key here not use default addmvc method , switch addmvccore instead higher degree of control of middleware.

the reason being, the order add options impact way mvc middleware behave. in experience dealing api using .net core, avoid addmvc in order full control on middleware.

there not fear here, can see addmvc nothing more template configures options addmvccore. can see source @ repository here.

i've grabbed code snippet related answer (maybe want take read more in-depth response how addmvccore works.

public void configureservices(iservicecollection services) {     // build customized mvc implementation, without using default addmvc(),     // instead use addmvccore(). repository link below:     // https://github.com/aspnet/mvc/blob/dev/src/microsoft.aspnetcore.mvc/mvcservicecollectionextensions.cs      services         .addmvccore(options =>         {             options.requirehttpspermanent = true; // not affect api requests             options.respectbrowseracceptheader = true; // false default                                                        //options.outputformatters.removetype<httpnocontentoutputformatter>();              // these 2 here show include custom formatters             options.outputformatters.add(new customoutputformatter());             options.inputformatters.add(new custominputformatter());         })         //.addapiexplorer()         //.addauthorization()         .addformattermappings()         //.addcachetaghelper()         //.adddataannotations()         //.addcors()         .addjsonformatters(); } 

your custom formatter

just little bit of nudge, no real serious concerns, here cleaner implementation of custom formatter might bit more mileage.

public class customoutputformatter : outputformatter {     public string contenttype { get; private set; }      public customoutputformatter()     {         contenttype = "application/custom";         supportedmediatypes.add(mediatypeheadervalue.parse("application/custom"));     }      protected override bool canwritetype(type type)     {         return true;     }      public override task writeresponsebodyasync(outputformatterwritecontext context)     {         var response = context.httpcontext.response;          // serialize it.         byte[] serializedbytes = ...         response.body.writeasync(serializedbytes, 0, serializedbytes.length).configureawait(false);          return task.fromresult(response);     } } 

Comments

Popular posts from this blog

php - Vagrant up error - Uncaught Reflection Exception: Class DOMDocument does not exist -

vue.js - Create hooks for automated testing -

Add new key value to json node in java -