13

我有一个带有 2 个控制器的自托管 Web API:

  • 对于控制器 1,我需要默认 DataContractSerializer(我正在公开 EF 5 POCO)
  • 对于控制器 2,我需要将参数 UseXmlSerializer 设置为 true 的 XmlFormatter(我正在公开一个 XmlDocument)

我尝试在控制器初始化期间设置格式化程序,但配置似乎是全局的,影响所有控制器:

public class CustomConfigAttribute : Attribute, IControllerConfiguration
{
    public void Initialize(HttpControllerSettings settings,
    HttpControllerDescriptor descriptor)
    {
        settings.Formatters.XmlFormatter.UseXmlSerializer = true;

    }
}

我该如何解决这个问题?

4

5 回答 5

10

你走在正确的轨道上。但是你需要XmlMediaTypeFormatter在你的配置属性中初始化一个新的实例,否则你会影响全局引用。

如您所知,您需要根据IControllerConfiguration界面创建 2 个属性。

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);
    }
}

然后用相关的属性装饰你的控制器

[Controller1ConfigAttribute]
public class Controller1Controller : ApiController
{

[Controller2ConfigAttribute]
public class Controller2Controller : ApiController
{
于 2012-11-15T08:52:10.013 回答
1

配置:

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

自定义格式化程序:

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

似乎有效,好吧不是那么优雅。删除默认的 Xml 格式化程序不起作用,所以我得出的结论是该框架仍在使用它。

于 2012-11-14T18:13:49.243 回答
0

我想你可以写一个 custom ActionFilterAttribute

OnActionExecuting中,将原始值存储在 HttpContext 中,然后在 中OnActionExecuted,恢复原始值。

于 2012-11-14T16:53:59.710 回答
0

控制器的操作本身不应该关心数据是如何序列化的。你应该能够请求数据,并且检索数据所需的任何格式都是相同的。

默认情况下,web api 序列化为 json 对象。但是,如果您将请求的内容类型设置为 xml,则应该返回相同的结果,但格式为 xml 而不是 json。

于 2012-11-14T17:08:53.173 回答
0

Mark Jones 的回答有一个很大的缺点:通过清除所有格式化程序,不可能请求不同的 ContentType 并使用相关的格式化程序。

为每个控制器启用 XMLSerializer 的更好方法是替换默认格式化程序。

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 });
    }
}

并像这样使用它:

[UseXMLSerializer]
public TestController : ApiController
{
    //Actions
}
于 2018-05-24T13:26:23.697 回答