【问题标题】:.net 4.5 Controller : Parameters polymorphism and custom Json Deserialization.net 4.5 控制器:参数多态性和自定义 Json 反序列化
【发布时间】:2018-07-09 18:04:15
【问题描述】:

我有一个 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... )
}

我需要获取最终对象,而不仅仅是控制器中的基础对象,以便将其传递给服务。

如何更改反序列化行为,但仅针对此操作或至少针对此控制器?

【问题讨论】:

    标签: c# .net controller json.net json-deserialization


    【解决方案1】:

    大家早上好。

    我受到这个问题的启发:Automatically deserialize to string-like class in Web.API controller

    这就是我所做的。

    1. 创建自定义 Json 转换器类

      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);
      }
      }
      
    2. 创建一个工厂类以返回所需的对象类型

      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);
      }
      
      }
      
    3. 最后在 StartUp 类中取消自定义 JsonConvertor

          var config = GlobalConfiguration.Configuration;
          var jsonSettings = config.Formatters.JsonFormatter.SerializerSettings;
          jsonSettings.Converters.Add(new BaseDtoJsonConvertor());
      

    仅此而已。任何时候我收到一个 Actionrequest Object 类型,它都会被反序列化并抛出我的自定义 jsonConvertor。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-12
      • 2021-12-20
      • 2022-09-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多