C# 版本控制WebAPI C-通过模型类对v1和v2的不同响应
我目前拥有一套API,并实现了某些API的v2。控制器级别I将URL设置为/v2/。我有一个要求,其中一个API响应是 Http响应C# 版本控制WebAPI C-通过模型类对v1和v2的不同响应,c#,asp.net-web-api,C#,Asp.net Web Api,我目前拥有一套API,并实现了某些API的v2。控制器级别I将URL设置为/v2/。我有一个要求,其中一个API响应是 Http响应 { "prd":"product name" } Product.cs public class ProductInfo { [JsonProperty("prd")] public string ProductName { get; set;} } 在API的版本2中,我想将JsonPropertyprd更改为JsonPropertyproduct
{
"prd":"product name"
}
Product.cs
public class ProductInfo
{
[JsonProperty("prd")]
public string ProductName { get; set;}
}
在API的版本2中,我想将JsonPropertyprd更改为JsonPropertyproduct_名称。如何根据API的版本动态更改属性名称并忽略某些属性。我不想复制服务层您可以在Json.Net中使用自定义来实现这一点。在这里,我创建了一个简单的演示示例。您可以根据API版本控制条件执行它
void Main()
{
var productInfo = new ProductInfo();
productInfo.ProductName = "Product Name";
var jsonResolver = new PropertyRenameSerializerContractResolver();
jsonResolver.RenameProperty(typeof(ProductInfo), "prd", "product_name");
var serializerSettings = new JsonSerializerSettings();
serializerSettings.ContractResolver = jsonResolver;
var json = JsonConvert.SerializeObject(productInfo, serializerSettings);
Console.WriteLine(json);
}
public class ProductInfo
{
[JsonProperty("prd")]
public string ProductName { get; set; }
}
public class PropertyRenameSerializerContractResolver : DefaultContractResolver
{
private readonly Dictionary<Type, Dictionary<string, string>> _renames;
public PropertyRenameSerializerContractResolver()
{
_renames = new Dictionary<Type, Dictionary<string, string>>();
}
public void RenameProperty(Type type, string propertyName, string newJsonPropertyName)
{
if (!_renames.ContainsKey(type))
_renames[type] = new Dictionary<string, string>();
_renames[type][propertyName] = newJsonPropertyName;
}
protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
{
var property = base.CreateProperty(member, memberSerialization);
if (IsRenamed(property.DeclaringType, property.PropertyName, out var newJsonPropertyName))
property.PropertyName = newJsonPropertyName;
return property;
}
private bool IsRenamed(Type type, string jsonPropertyName, out string newJsonPropertyName)
{
Dictionary<string, string> renames;
if (!_renames.TryGetValue(type, out renames) || !renames.TryGetValue(jsonPropertyName, out newJsonPropertyName))
{
newJsonPropertyName = null;
return false;
}
return true;
}
}
我在一个与您的场景相匹配的场景中使用了这个。有关更多详细信息,请参阅以下文章
不确定这是一个好的方法,你应该为每个版本的API复制你的类。你应该考虑使用DTOS而不是通过API公开你的域模型。这样,您就可以轻松地将ProductInfo映射到v1/v2端点的DTO。我建议您阅读这一良好实践的原因。您最好复制DTO,而不是在维护方面尝试动态更改属性名称。我更喜欢使用ApiVersion属性,并确保每个版本都有自己的特定契约。调用方应该在URL或标题或查询字符串中指定版本号。这样我们就可以确切地知道应该使用哪个模式。使解决方案更加类型安全。尝试了几种不同的技术,但似乎没有一种能完全起作用,创建了一个回购协议,以查看外部别名是否有助于向下投票,因为我认为这是过分的,并且使OP的代码变得更加复杂。@我谦虚地接受了您的向下投票,但我认为您已经将此视为实现此目的的方法之一。除此之外,你认为所有人都在考虑OP的代码来回答这个问题吗?有时候我们需要一些有用的东西。当然,我认为你的答案是实现这一点的一种方法,这就是你发布它的原因,不是吗?。我想在回答之前,很少有人考虑OPS代码。是的,最终一个人需要一些有用的东西。在本例中,请参阅@Boxiom的注释。@KeyurRamoliya我引用了同一个站点并使用了ContractResolver并成功地重命名了属性。感谢这是一种情况,因为你能做一些事情,你绝对不应该真的去做。
{"product_name":"Product Name"}