.net 4.5 控制器:参数多态和自定义 Json 反序列化
.net 4.5 Controller : Parameters polymorphism and custom Json Deserialization
我有一个 API,其中有一个同步控制器。
这个控制器只有一个动作函数:ActionRequest
public IHttpActionResult ActionRequest([FromBody]ActionRequestDto model)
{
//EXAMPLE OF PASSING AND ARTICLE IN OBJECT THREW POST METHOD
ArticleDto article = null;
if(model.ActionType == "Article"){
article = (ArticleDto)model.Object; //Problem ==> model.Object looses all articles information and cannot be cast to article
}
}
此功能应该像路由器一样工作。它读取操作请求并调用适当的存储库。
ActionRequest 对象具有以下结构:
public class ActionRequestDto
{
public string ActionType { get; set; }
public string ObjectType { get; set; }
public bool Transmited { get; set; } = false;
public DateTime CreationDate { get; set; }
public int RequestNumber { get; set; }
public string Reference { get; set; }
public BaseDto Object { get; set; }// this is where the data is passed.
//it can be any type extending from BaseDto (ArticleDto, CustomerDto... )
}
我需要获取最终对象,而不仅仅是控制器中的基础对象,这样我才能将它传递给服务。
如何更改反序列化行为但仅针对此操作或至少针对此控制器?
大家早上好。
我被这个问题启发了:
这就是我所做的。
创建自定义 Json 转换器 class
public class BaseDtoJsonConvertor : JsonConverter
{
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
var actionRequestDto = (ActionRequestDto)value;
writer.WriteStartObject();
writer.WritePropertyName("ActionRequestDto");
serializer.Serialize(writer, actionRequestDto.ToString());
writer.WriteEndObject();
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
// Variables to be set along with sensing variables
ActionRequestDto actionRequestDto = new ActionRequestDto();
// Read the properties
while (reader.Read())
{
if (reader.TokenType != JsonToken.PropertyName)
{
break;
}
var propertyName = (string)reader.Value;
if (!reader.Read())
{
continue;
}
// Set the group
if (propertyName.Equals("object", StringComparison.OrdinalIgnoreCase))
{
actionRequestDto.Object = JsonSerializerBaseObjectFactory.DeserializeObject(actionRequestDto.ObjectType, reader, serializer);
}
if (propertyName.Equals("ActionType", StringComparison.OrdinalIgnoreCase))
{
actionRequestDto.ActionType = serializer.Deserialize<string>(reader);
}
if (propertyName.Equals("ObjectType", StringComparison.OrdinalIgnoreCase))
{
actionRequestDto.ObjectType = serializer.Deserialize<string>(reader);
}
if (propertyName.Equals("Transmited", StringComparison.OrdinalIgnoreCase))
{
actionRequestDto.Transmited = serializer.Deserialize<bool>(reader);
}
if (propertyName.Equals("CreationDate", StringComparison.OrdinalIgnoreCase))
{
actionRequestDto.CreationDate = serializer.Deserialize<DateTime>(reader);
}
if (propertyName.Equals("RequestNumber", StringComparison.OrdinalIgnoreCase))
{
actionRequestDto.RequestNumber = serializer.Deserialize<int>(reader);
}
if (propertyName.Equals("Reference", StringComparison.OrdinalIgnoreCase))
{
actionRequestDto.Reference = serializer.Deserialize<string>(reader);
}
}
return actionRequestDto;
}
public override bool CanConvert(Type objectType)
{
return objectType == typeof(ActionRequestDto);
}
}
创建一个工厂Class到return需要的对象类型
class JsonSerializerBaseObjectFactory
{
public enum Types
{
Article,
Basket,
Customer,
WishList,
User,
Tarif,
Store,
Stock,
ShippingTaxe,
Seller,
SalesDocument,
Promotion,
Payment,
InventoryTransaction,
Inventory,
Family,
Etablissement,
Dimension,
Depot,
CreditCard,
Country,
Commande,
Category,
Cashier,
AvailableQuantity,
ArticleRequest
};
public static BaseDto DeserializeObject(string type, JsonReader reader, JsonSerializer serializer)
{
Types typeRes;
if (Enum.TryParse(type, out typeRes))
{
switch (typeRes)
{
case Types.Article:
return serializer.Deserialize<ArticleDto>(reader);
case Types.Basket:
return serializer.Deserialize<BasketDto>(reader);
case Types.Customer:
return serializer.Deserialize<CustomerDto>(reader);
default:
return serializer.Deserialize<BaseDto>(reader);
}
}
return serializer.Deserialize<BaseDto>(reader);
}
}
终于在 StartUp 中 Class Deglare the Custom JsonConvertor
var config = GlobalConfiguration.Configuration;
var jsonSettings = config.Formatters.JsonFormatter.SerializerSettings;
jsonSettings.Converters.Add(new BaseDtoJsonConvertor());
仅此而已。每当我收到 Actionrequest 对象类型时,它都会反序列化并抛出我的自定义 jsonConvertor。
我有一个 API,其中有一个同步控制器。 这个控制器只有一个动作函数:ActionRequest
public IHttpActionResult ActionRequest([FromBody]ActionRequestDto model)
{
//EXAMPLE OF PASSING AND ARTICLE IN OBJECT THREW POST METHOD
ArticleDto article = null;
if(model.ActionType == "Article"){
article = (ArticleDto)model.Object; //Problem ==> model.Object looses all articles information and cannot be cast to article
}
}
此功能应该像路由器一样工作。它读取操作请求并调用适当的存储库。
ActionRequest 对象具有以下结构:
public class ActionRequestDto
{
public string ActionType { get; set; }
public string ObjectType { get; set; }
public bool Transmited { get; set; } = false;
public DateTime CreationDate { get; set; }
public int RequestNumber { get; set; }
public string Reference { get; set; }
public BaseDto Object { get; set; }// this is where the data is passed.
//it can be any type extending from BaseDto (ArticleDto, CustomerDto... )
}
我需要获取最终对象,而不仅仅是控制器中的基础对象,这样我才能将它传递给服务。
如何更改反序列化行为但仅针对此操作或至少针对此控制器?
大家早上好。
我被这个问题启发了:
这就是我所做的。
创建自定义 Json 转换器 class
public class BaseDtoJsonConvertor : JsonConverter { public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { var actionRequestDto = (ActionRequestDto)value; writer.WriteStartObject(); writer.WritePropertyName("ActionRequestDto"); serializer.Serialize(writer, actionRequestDto.ToString()); writer.WriteEndObject(); } public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { // Variables to be set along with sensing variables ActionRequestDto actionRequestDto = new ActionRequestDto(); // Read the properties while (reader.Read()) { if (reader.TokenType != JsonToken.PropertyName) { break; } var propertyName = (string)reader.Value; if (!reader.Read()) { continue; } // Set the group if (propertyName.Equals("object", StringComparison.OrdinalIgnoreCase)) { actionRequestDto.Object = JsonSerializerBaseObjectFactory.DeserializeObject(actionRequestDto.ObjectType, reader, serializer); } if (propertyName.Equals("ActionType", StringComparison.OrdinalIgnoreCase)) { actionRequestDto.ActionType = serializer.Deserialize<string>(reader); } if (propertyName.Equals("ObjectType", StringComparison.OrdinalIgnoreCase)) { actionRequestDto.ObjectType = serializer.Deserialize<string>(reader); } if (propertyName.Equals("Transmited", StringComparison.OrdinalIgnoreCase)) { actionRequestDto.Transmited = serializer.Deserialize<bool>(reader); } if (propertyName.Equals("CreationDate", StringComparison.OrdinalIgnoreCase)) { actionRequestDto.CreationDate = serializer.Deserialize<DateTime>(reader); } if (propertyName.Equals("RequestNumber", StringComparison.OrdinalIgnoreCase)) { actionRequestDto.RequestNumber = serializer.Deserialize<int>(reader); } if (propertyName.Equals("Reference", StringComparison.OrdinalIgnoreCase)) { actionRequestDto.Reference = serializer.Deserialize<string>(reader); } } return actionRequestDto; } public override bool CanConvert(Type objectType) { return objectType == typeof(ActionRequestDto); } }
创建一个工厂Class到return需要的对象类型
class JsonSerializerBaseObjectFactory { public enum Types { Article, Basket, Customer, WishList, User, Tarif, Store, Stock, ShippingTaxe, Seller, SalesDocument, Promotion, Payment, InventoryTransaction, Inventory, Family, Etablissement, Dimension, Depot, CreditCard, Country, Commande, Category, Cashier, AvailableQuantity, ArticleRequest }; public static BaseDto DeserializeObject(string type, JsonReader reader, JsonSerializer serializer) { Types typeRes; if (Enum.TryParse(type, out typeRes)) { switch (typeRes) { case Types.Article: return serializer.Deserialize<ArticleDto>(reader); case Types.Basket: return serializer.Deserialize<BasketDto>(reader); case Types.Customer: return serializer.Deserialize<CustomerDto>(reader); default: return serializer.Deserialize<BaseDto>(reader); } } return serializer.Deserialize<BaseDto>(reader); } }
终于在 StartUp 中 Class Deglare the Custom JsonConvertor
var config = GlobalConfiguration.Configuration; var jsonSettings = config.Formatters.JsonFormatter.SerializerSettings; jsonSettings.Converters.Add(new BaseDtoJsonConvertor());
仅此而已。每当我收到 Actionrequest 对象类型时,它都会反序列化并抛出我的自定义 jsonConvertor。