自定义MediaTypeFormatter (Serializer)用于ApiController特定的方法

本文关键字:方法 ApiController 用于 MediaTypeFormatter Serializer 自定义 | 更新日期: 2023-09-27 18:05:12

我有ApiController,其中一个方法需要自定义序列化。

    public async Task<Session> PostSession([FromBody] Session session)

有大量的会话对象,持有一切和消费者不想做得到超过一半的它,通常我可以只是装饰属性与[XmlIgnore()]和完成,但是这个对象是通过许多api内部传递和删除这些会打破这些机制。

另一种解决方案是将该对象替换为其他对象,如CastratedSession并返回该对象。我不能这样做,因为相同的端点正在被期望获得Session的现有第三方api调用,否则他们将不得不重写他们的东西(不会发生)。

然后我提议创建一个第三方可以调用的不同端点-但架构师反对并说要根据他们将在header中设置的特定content-type值来做自定义MediaTypeFormatter,问题是我们已经在使用相同的控制器自定义MediaTypeFormatter,并且我理解的方式开箱即用的方式只能在每个控制器的配置中设置它们

public static void ConfigureApis(HttpConfiguration config)
{
    config.Formatters.Add(new CustomJsonFormatter()); 
    config.Formatters.Add(new CustomXmlFormatter()); 
}

这让我陷入了困境。

我如何(可以)在ApiController上设置自定义MediaTypeFormatter per方法?

自定义MediaTypeFormatter (Serializer)用于ApiController特定的方法

您可以编写一个自定义动作过滤器,覆盖OnActionExecuting方法来检查目标动作,然后将适当的格式化器添加到配置中。

internal class DecisionMakingFilter : ActionFilterAttribute
{
    public override void OnActionExecuting(HttpActionContext actionContext)
    {
        var actionName= actionContext.ActionDescriptor.ActionName;
        if(actionName == "Some Foo")
        {
            actionContext.RequestContext.Configuration.Formatters.Add(new CustomMediaFormatter());
        }
        base.OnActionExecuting(actionContext);
        actionContext.RequestContext.Configuration.Formatters.Remove(new CustomMediaFormatter());
    }
}

我自己想出了一个解决办法

我用EvenMoreCustomXmlFormatter()继承并替换了CustomXmlFormatter()

然后在WriteToStreamAsync做了这个:

  public override Task WriteToStreamAsync(Type type, object value, Stream writeStream, HttpContent content, TransportContext transportContext)
    {
        if (content.Headers.ContentType.MediaType == "text/sessionXml") // this was agreed with 3rd party
        {
            //do my serialization stuff
        }
        else
        {
            return base.WriteToStreamAsync(type, value, writeStream, content, transportContext);
        }
    }