ApiController 特定方法的自定义 MediaTypeFormatter (Serializer)
Custom MediaTypeFormatter (Serializer) for ApiController specific method
我有 ApiController
并且其中一种方法需要自定义序列化。
public async Task<Session> PostSession([FromBody] Session session)
有大量 Session object 可以容纳所有东西,消费者不想得到超过一半,通常我可以用 [XmlIgnore()]
装饰属性并完成,然而,这个 object 正在通过许多 API 在内部传递,删除这些 API 会破坏这些机制。
另一种解决方案是将 object 替换为不同的 CastratedSession
和 return。我不能这样做,因为现有的第 3 方 API 正在调用相同的端点,这些 API 期望获得 Session
,否则他们将不得不重写他们的东西(不会发生)。
然后我提议创建一个不同的端点,这个第 3 方可以调用 - 但架构师 objected 并说要根据特定的 content-type
值进行自定义 MediaTypeFormatter
在 header 中设置,问题是我们已经在同一个控制器自定义 MediaTypeFormatter
中使用,而且我理解开箱即用的方式只能在每个控制器的配置中设置它们
public static void ConfigureApis(HttpConfiguration config)
{
config.Formatters.Add(new CustomJsonFormatter());
config.Formatters.Add(new CustomXmlFormatter());
}
哪一种把我逼到墙角。
如何(可以)在 ApiController 上为每个方法设置自定义 MediaTypeFormatter
?
您可以编写自定义操作过滤器,覆盖 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());
}
}
我自己想出了一个解决方法
我继承并替换了 CustomXmlFormatter()
为 EvenMoreCustomXmlFormatter()
然后在 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);
}
}
希望这能为您节省一些时间。
我有 ApiController
并且其中一种方法需要自定义序列化。
public async Task<Session> PostSession([FromBody] Session session)
有大量 Session object 可以容纳所有东西,消费者不想得到超过一半,通常我可以用 [XmlIgnore()]
装饰属性并完成,然而,这个 object 正在通过许多 API 在内部传递,删除这些 API 会破坏这些机制。
另一种解决方案是将 object 替换为不同的 CastratedSession
和 return。我不能这样做,因为现有的第 3 方 API 正在调用相同的端点,这些 API 期望获得 Session
,否则他们将不得不重写他们的东西(不会发生)。
然后我提议创建一个不同的端点,这个第 3 方可以调用 - 但架构师 objected 并说要根据特定的 content-type
值进行自定义 MediaTypeFormatter
在 header 中设置,问题是我们已经在同一个控制器自定义 MediaTypeFormatter
中使用,而且我理解开箱即用的方式只能在每个控制器的配置中设置它们
public static void ConfigureApis(HttpConfiguration config)
{
config.Formatters.Add(new CustomJsonFormatter());
config.Formatters.Add(new CustomXmlFormatter());
}
哪一种把我逼到墙角。
如何(可以)在 ApiController 上为每个方法设置自定义 MediaTypeFormatter
?
您可以编写自定义操作过滤器,覆盖 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());
}
}
我自己想出了一个解决方法
我继承并替换了 CustomXmlFormatter()
为 EvenMoreCustomXmlFormatter()
然后在 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);
}
}
希望这能为您节省一些时间。