You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Web API动作过滤器中如何在运行时处理未知类型?

解决方案

你遇到的问题是因为Json.NET的DeserializeObject<dynamic>返回的是JObject实例,而非与原对象同类型的实例,后续Web API序列化时会因类型不匹配导致输出异常。下面是两种无需反射、也不需要提前知道具体类型的实现方式:

方法一:直接操作JObject(推荐,更安全)

通过将原对象序列化为JObject,直接修改其属性值后再转换回原类型,既避免了字符串替换的误操作,也能保证返回对象类型与原类型一致:

public class MyFilterAttribute : ActionFilterAttribute
{
    public override void OnActionExecuted(ActionExecutedContext context)
    {
        var okResult = context.Result as OkObjectResult;
        if (okResult?.Value == null) return;

        // 将原对象转换为JObject,方便直接操作属性
        var jObject = JObject.FromObject(okResult.Value);

        // 场景1:修改指定字段(比如name字段)
        if (jObject.TryGetValue("name", out JToken nameToken) && nameToken.Type == JTokenType.String)
        {
            string updatedName = nameToken.ToString().Replace("John", "John Smith");
            jObject["name"] = updatedName;
        }

        // 场景2:全局替换所有字符串字段中的"John"(按需使用)
        foreach (var stringToken in jObject.Descendants()
                                           .OfType<JValue>()
                                           .Where(t => t.Type == JTokenType.String))
        {
            stringToken.Value = stringToken.Value.ToString().Replace("John", "John Smith");
        }

        // 转换回原对象类型,确保后续序列化正常
        var modifiedValue = jObject.ToObject(okResult.Value.GetType());
        okResult.Value = modifiedValue;
    }
}

方法二:改进字符串替换+动态类型转换

如果你坚持使用字符串替换的方式,需要确保反序列化时使用原对象的类型,而非dynamic:

public class MyFilterAttribute : ActionFilterAttribute
{
    public override void OnActionExecuted(ActionExecutedContext context)
    {
        var okResult = context.Result as OkObjectResult;
        if (okResult?.Value == null) return;

        string json = JsonConvert.SerializeObject(okResult.Value);
        json = json.Replace("John", "John Smith");

        // 使用原对象的类型进行反序列化,而非dynamic
        var targetType = okResult.Value.GetType();
        var modifiedResultValue = JsonConvert.DeserializeObject(json, targetType);

        okResult.Value = modifiedResultValue;
    }
}

关键说明

  • 方法一中的JObject操作更精准,不会误替换其他字段中包含的"John"(比如字段值为"JohnDoe"不会被改成"John SmithDoe")。
  • 两种方法都通过okResult.Value.GetType()获取运行时类型,无需提前指定具体类型,也不需要反射。
  • 避免直接使用dynamic是因为Json.NET的dynamic本质是JObject,Web API默认序列化器处理JObject时可能出现字段名大小写不匹配、值格式异常等问题。

内容的提问来源于stack exchange,提问作者MVCKarl

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 16:53:15