【问题标题】:Custom JsonConverter not working on WebAPI object deserialization自定义 JsonConverter 不适用于 WebAPI 对象反序列化
【发布时间】:2019-06-03 11:41:06
【问题描述】:

我有一个模型对象,我发送到浏览器并被发送回给我。我希望对该对象中的 ID 值进行加密。我创建了一个自定义的 JsonConverter 来加密字符串然后解密它。

public class SecretItem
{
    [JsonConverter(typeof(EncryptedIdConverter))]
    public string Id { get; set; }
    public string Name { get; set; }
}

这是我的 EncryptedIdConverter 类

class EncryptedIdConverter : JsonConverter
{
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        string encryptedValue = (string)value;

        if (!string.IsNullOrWhiteSpace(encryptedValue))
            encryptedValue = Encryption.EncryptString(encryptedValue);

        serializer.Serialize(writer, encryptedValue);
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        string decryptedString = (string)reader.Value;

        if (!string.IsNullOrWhiteSpace(decryptedString))
            decryptedString = Encryption.DecryptString(decryptedString);

        return decryptedString;
    }

    public override bool CanConvert(Type objectType)
    {
        return typeof(string).IsAssignableFrom(objectType);
    }
}

如果我尝试调用 JsonConvert.Serialization 函数,一切正常。

JsonConvert.SerializeObject(secretItem)
JsonConvert.DeserializeObject<SecretItem>([JSON secretItem]);

当我返回 HttpActionResult Ok(secretItem)... 时,浏览器也会得到加密的 Id 字符串。

但是,当我将数据发布回我的控制器时,我的 webapi 方法没有获得解密的属性。它跳过了 JsonConverter。

public async Task<IHttpActionResult> Post(SecretItem secretItem)
{
    // Not decrypted
    var decryptedId = secretItem.Id;
}

为什么反序列化逻辑与我的 WebAPI 中的序列化逻辑工作方式不同?我什至不知道从哪里开始调试。

我们正在使用 Newtonsoft.Json 10.0.0.0、MVC5、.NET Framework 4.6.1。

【问题讨论】:

  • 您是否尝试过断点自定义转换器以确保它被调用?
  • 是的。当我直接调用 JsonConvert 时会调用它。它在 WebAPI 的序列化过程中被调用。我不知道为什么在 WebAPI 的反序列化过程中会跳过它。
  • 你的 CanConvert 方法是什么?
  • 我将我的 EncryptedIdConverter 类添加到原始帖子中,因为它太长而无法添加为评论。
  • @MohamedElrashid 当我添加断点时,我没有看到 CanConvert 方法在我的任何序列化过程中被调用......当我从控制器返回它并被序列化或当我调用 JsonConvert .De/SerializeObject 直接。

标签: c# json.net asp.net-web-api2


【解决方案1】:

你的 Global.asax 怎么样

protected void Application_Start()
{
  AreaRegistration.RegisterAllAreas();
  GlobalConfiguration.Configure(WebApiConfig.Register);
  FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
  RouteConfig.RegisterRoutes(RouteTable.Routes);
  BundleConfig.RegisterBundles(BundleTable.Bundles);
}

它应该可以工作

也许你需要一个 TypeConverter

模型绑定

当 Web API 调用控制器上的方法时,它必须为参数设置值,这个过程称为绑定

  • 这称为模型绑定

     Post(SecretItem secretItem)
    
  • 模型绑定使用 TypeConverter

JSON 序列化

  • 这称为 JSON 序列化

    HttpActionResult Ok(secretItem)
    
  • JSON 序列化使用 JsonConverter

文档

更多

【讨论】:

    【解决方案2】:

    事实证明代码工作正常。问题是在正在测试的 POST 上,内容类型未设置为“application/json”。因此,它没有使用 JsonNetFormatter,因此跳过了转换器。

    设置 contentType 后,一切正常!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-12-27
      • 2022-01-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-28
      • 2022-01-03
      相关资源
      最近更新 更多