从WebApi中的蛇案JSON自动绑定Pascal Case C#模型

Roc*_*lan 5 c# asp.net json.net asp.net-web-api2

我正在尝试从WebApi v2(完整框架,而不是点网核心)中的snake_cased JSON绑定我的PascalCased c#模型。

这是我的API:

public class MyApi : ApiController
{
    [HttpPost]
    public IHttpActionResult DoSomething([FromBody]InputObjectDTO inputObject)
    {
        database.InsertData(inputObject.FullName, inputObject.TotalPrice)
        return Ok();
    }
}
Run Code Online (Sandbox Code Playgroud)

这是我的输入对象:

public class InputObjectDTO
{
    public string FullName { get; set; }
    public int TotalPrice { get; set; }
    ...
}
Run Code Online (Sandbox Code Playgroud)

我的问题是JSON看起来像这样:

{
    "full_name": "John Smith",
    "total_price": "20.00"
}
Run Code Online (Sandbox Code Playgroud)

我知道我可以使用JsonProperty属性:

public class InputObjectDTO
{
    [JsonProperty(PropertyName = "full_name")]
    public string FullName { get; set; }

    [JsonProperty(PropertyName = "total_price")]
    public int TotalPrice { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

但是我的InputObjectDTO 很大,还有很多其他类似的东西。它具有数百个全部使用蛇形封装的属性,最好不必为每个属性指定JsonProperty属性。我可以使其“自动”工作吗?也许使用自定义模型活页夹或自定义json转换器?

Bri*_*ers 5

无需重新发明轮子。Json.Net已经有一个SnakeCaseNamingStrategy类可以完全满足您的需求。你只需要将其设置为NamingStrategyDefaultContractResolver通过设置。

将此行添加到Register您的WebApiConfig类中的方法:

config.Formatters.JsonFormatter.SerializerSettings.ContractResolver =
    new DefaultContractResolver { NamingStrategy = new SnakeCaseNamingStrategy() };
Run Code Online (Sandbox Code Playgroud)

这是一个演示该概念的演示(控制台应用程序):https : //dotnetfiddle.net/v5siz7


如果要对某些类而不是其他类应用蛇形套管,可以通过应用[JsonObject]指定命名策略的属性来实现,例如:

[JsonObject(NamingStrategyType = typeof(SnakeCaseNamingStrategy))]
public class InputObjectDTO
{
    public string FullName { get; set; }
    public decimal TotalPrice { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

通过属性设置的命名策略优先于通过解析器设置的命名策略,因此您可以在解析器中设置默认策略,然后在需要时使用属性覆盖它。(有附带Json.Net 3个的命名策略:SnakeCaseNamingStrategyCamelCaseNamingStrategyDefaultNamingStrategy)。


现在,如果您要使用一种命名策略对序列进行序列化并针对同一类使用不同的策略进行序列化,那么上述两种解决方案都不适合您,因为命名策略将在Web API中双向应用。因此,在这种情况下,您将需要一些自定义内容,例如@icepickle的答案中所示的内容,以控制何时应用每个内容。