我想仅针对我的一个控制器更改传入的请求。因此,我将其添加到我的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