将Snakecase强制对每个控制器的WebAPI进行启用



我想仅针对我的一个控制器更改传入的请求。因此,我将其添加到我的Global.asax中,它可以正常工作:

HttpConfiguration config = GlobalConfiguration.Configuration;
config.Formatters.JsonFormatter.SerializerSettings = new Newtonsoft.Json.JsonSerializerSettings
{
    ContractResolver = new DefaultContractResolver
    {
        NamingStrategy = new SnakeCaseNamingStrategy()
    }
};

,但它将更改应用于所有控制器。我只想将其应用于我的一个控制器。我还找到了这个答案,然后根据以下方式编写了此代码:

public void Initialize(HttpControllerSettings controllerSettings, HttpControllerDescriptor controllerDescriptor)
{
    var formatter = controllerSettings.Formatters.OfType<JsonMediaTypeFormatter>().Single();
    controllerSettings.Formatters.Remove(formatter);
    formatter = new JsonMediaTypeFormatter
    {
        SerializerSettings = { ContractResolver = new DefaultContractResolver { NamingStrategy = new SnakeCaseNamingStrategy() } }
    };
    controllerSettings.Formatters.Add(formatter);
}

,但不幸的是,它仅用于序列化输出。有没有办法将其定义用于避免输入?

您可以使用棘手的媒体类型格式来完成您需要的事情。通常,自定义格式化器覆盖方法CanReadType()/CanWriteType()ReadFromStreamAsync()/WriteToStreamAsync()。在您的情况下,CanWriteType()应始终返回false,因为您没有在自定义序列化方面附带。关于次要化,您可以使用标准JsonMediaTypeFormatter(通过继承或聚合),并将其SerializerSettings设置为使用SnakeCaseNamingStrategy

public class SnakeCaseJsonFormatter : JsonMediaTypeFormatter
{
    public SnakeCaseJsonFormatter()
    {
        SerializerSettings = new JsonSerializerSettings
        {
            ContractResolver = new DefaultContractResolver
            {
                NamingStrategy = new SnakeCaseNamingStrategy()
            }
        };
    }
    public override bool CanWriteType(Type type)
    {
        return false;
    }
    public override Task WriteToStreamAsync(Type type, object value, Stream writeStream, HttpContent content, TransportContext transportContext)
    {
        throw new NotImplementedException();
    }
}

其余部分是在控制器级别上应用这种自定义格式化器。您可以使用实现IControllerConfiguration接口的自定义属性来执行此操作。在Initialize()中,方法将您的自定义格式化设置为第一个位置,以便优先于标准JsonMediaTypeFormatter。您不应删除标准JsonMediaTypeFormatter,因为它将处理序列化数据:

public sealed class SnakeCaseNamingAttribute : Attribute, IControllerConfiguration
{
    public void Initialize(HttpControllerSettings controllerSettings, HttpControllerDescriptor controllerDescriptor)
    {
        controllerSettings.Formatters.Insert(0, new SnakeCaseJsonFormatter());
    }
}

现在,只需将此属性应用于您想要的控制器上,瞧:

[SnakeCaseNaming]
public class ValuesController : ApiController

相关内容

  • 没有找到相关文章

最新更新