ASP.NET Web API Controller Specific Serializer

前端 未结 5 1910
深忆病人
深忆病人 2020-12-15 23:46

I\'ve a self host Web API with 2 controllers:

  • For controller 1, I need default DataContractSerializer (I\'m exposing EF 5 POCO)
  • For controller 2, I ne
相关标签:
5条回答
  • 2020-12-16 00:02

    You were very much on the right track. But you need to initallise a new instance of the XmlMediaTypeFormatter in your config attributes otherwise you will affect the global reference.

    As you know, you need to create 2 attributes based on the IControllerConfiguration interface.

    public class Controller1ConfigAttribute : Attribute, IControllerConfiguration
    {
        public void Initialize(HttpControllerSettings controllerSettings,
                               HttpControllerDescriptor controllerDescriptor)
        {
            var xmlFormater = new XmlMediaTypeFormatter {UseXmlSerializer = true};
    
            controllerSettings.Formatters.Clear();
            controllerSettings.Formatters.Add(xmlFormater);
        }
    }
    
    public class Controller2ConfigAttribute : Attribute, IControllerConfiguration
    {
        public void Initialize(HttpControllerSettings controllerSettings,
                               HttpControllerDescriptor controllerDescriptor)
        {
            var xmlFormater = new XmlMediaTypeFormatter();
            controllerSettings.Formatters.Clear();
            controllerSettings.Formatters.Add(xmlFormater);
        }
    }
    

    Then decorate your controllers with the relevant attribute

    [Controller1ConfigAttribute]
    public class Controller1Controller : ApiController
    {
    
    [Controller2ConfigAttribute]
    public class Controller2Controller : ApiController
    {
    
    0 讨论(0)
  • 2020-12-16 00:04

    Mark Jones' answer has a big downside: By clearing all formatters it is not possible to request different ContentTypes and make use of the relevant formatter.

    A better way to enable the XMLSerializer per Controller is to replace the default formatter.

    public class UseXMLSerializerAttribute : Attribute, IControllerConfiguration
    {
        public void Initialize(HttpControllerSettings controllerSettings, HttpControllerDescriptor controllerDescriptor)
        {
            // Find default XMLFormatter
            var xmlFormatter = controllerSettings.Formatters.FirstOrDefault(c => c.SupportedMediaTypes.Any(x => x.MediaType == "application/xml"));
    
            if (xmlFormatter != null)
            {
                // Remove default formatter
                controllerSettings.Formatters.Remove(xmlFormatter);
            }
    
            // Add new XMLFormatter which uses XmlSerializer
            controllerSettings.Formatters.Add(new XmlMediaTypeFormatter { UseXmlSerializer = true });
        }
    }
    

    And use it like this:

    [UseXMLSerializer]
    public TestController : ApiController
    {
        //Actions
    }
    
    0 讨论(0)
  • 2020-12-16 00:06

    Configuration:

    config.Formatters.Remove(config.Formatters.JsonFormatter);
    config.Formatters.Insert(0, new CustomXmlMediaTypeFormatter());
    

    The Custom formatter:

    public class CustomXmlMediaTypeFormatter : XmlMediaTypeFormatter
    {
        public CustomXmlMediaTypeFormatter()
        {
            UseXmlSerializer = true;
        }
    }
    

    This seems to work, ok not so elegant. Removing default Xml Formatter does not work, so I concluded that the framework is somehow still using it.

    0 讨论(0)
  • 2020-12-16 00:08

    the controllers actions themselves should not be concerned with how the data is serialized. yo should be able to request the data and any format necessary the operation to retrieve the data would be the same.

    by default web api serialized to json objects. however if you set the content type of the request to xml is should return the same result, but formatted as xml instead of json.

    0 讨论(0)
  • 2020-12-16 00:24

    I think you could write a custom ActionFilterAttribute.

    In OnActionExecuting, store away the original values in the HttpContext and then in OnActionExecuted, restore the original values.

    0 讨论(0)
提交回复
热议问题