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

ASP.NET Core 10 Web API如何实现WCF中__type的功能?

在ASP.NET Core Web API中实现基类参数的子类识别(替代WCF的__type机制)

方法一:通过System.Text.Json配置类型信息(推荐)

这是最贴合WCF __type机制的方案,利用ASP.NET Core默认的JSON序列化器实现类型自动识别。

1. 配置Json序列化选项

在Program.cs中添加序列化配置,指定基类Fruit的子类映射,并沿用__type作为类型识别字段:

builder.Services.AddControllers()
    .AddJsonOptions(options =>
    {
        options.JsonSerializerOptions.TypeInfoResolver = new DefaultJsonTypeInfoResolver
        {
            Modifiers =
            {
                typeInfo =>
                {
                    if (typeInfo.Type == typeof(Fruit))
                    {
                        typeInfo.PolymorphismOptions = new JsonPolymorphismOptions
                        {
                            TypeDiscriminatorPropertyName = "__type", // 和WCF的__type字段对齐
                            IgnoreUnrecognizedTypeDiscriminators = true,
                            DerivedTypes =
                            {
                                new JsonDerivedType(typeof(Apple), nameof(Apple)),
                                new JsonDerivedType(typeof(Orange), nameof(Orange))
                            }
                        };
                    }
                }
            }
        };
    });

2. 保持原有Action逻辑不变

你的服务端方法无需修改,序列化器会自动根据__type字段将JSON反序列化为对应子类:

public class FruitController : ControllerBase
{
    [HttpPost("SomeMethod")]
    public IActionResult SomeMethod([FromBody] Fruit fruit)
    {
        if (fruit is Apple apple)
        {
            // 处理Apple类型逻辑
            return Ok($"处理Apple对象");
        }
        else if (fruit is Orange orange)
        {
            // 处理Orange类型逻辑
            return Ok($"处理Orange对象");
        }
        else
        {
            return Ok("处理未知Fruit子类");
        }
    }
}

方法二:客户端配合实现兼容

如果客户端是.NET应用,需要在序列化请求对象时包含__type字段:

var apple = new Apple();
var jsonOptions = new JsonSerializerOptions
{
    TypeInfoResolver = new DefaultJsonTypeInfoResolver
    {
        Modifiers =
        {
            typeInfo =>
            {
                if (typeInfo.Type == typeof(Fruit))
                {
                    typeInfo.PolymorphismOptions = new JsonPolymorphismOptions
                    {
                        TypeDiscriminatorPropertyName = "__type",
                        DerivedTypes =
                        {
                            new JsonDerivedType(typeof(Apple), nameof(Apple)),
                            new JsonDerivedType(typeof(Orange), nameof(Orange))
                        }
                    };
                }
            }
        }
    }
};

var json = JsonSerializer.Serialize(apple, jsonOptions);
var content = new StringContent(json, Encoding.UTF8, "application/json");

var httpClient = new HttpClient();
var response = await httpClient.PostAsync("https://你的API地址/SomeMethod", content);

非.NET客户端(如Postman)可手动构造请求JSON:

{
    "__type": "Apple",
    // Apple的其他属性字段
}

方法三:自定义模型绑定器(复杂场景)

如果需要更灵活的类型判断逻辑,可以自定义模型绑定器:

1. 实现自定义绑定器

public class FruitModelBinder : IModelBinder
{
    public Task BindModelAsync(ModelBindingContext bindingContext)
    {
        if (bindingContext == null)
            throw new ArgumentNullException(nameof(bindingContext));

        // 读取请求体JSON
        using var reader = new StreamReader(bindingContext.HttpContext.Request.Body);
        var json = reader.ReadToEnd();
        
        // 解析__type字段
        var jsonDoc = JsonDocument.Parse(json);
        if (jsonDoc.RootElement.TryGetProperty("__type", out var typeElement))
        {
            var typeName = typeElement.GetString();
            Type targetType = typeName switch
            {
                nameof(Apple) => typeof(Apple),
                nameof(Orange) => typeof(Orange),
                _ => typeof(Fruit)
            };
            
            // 反序列化为目标类型
            var fruit = JsonSerializer.Deserialize(json, targetType);
            bindingContext.Result = ModelBindingResult.Success(fruit);
        }
        else
        {
            // 默认反序列化为基类Fruit
            var fruit = JsonSerializer.Deserialize<Fruit>(json);
            bindingContext.Result = ModelBindingResult.Success(fruit);
        }
        
        return Task.CompletedTask;
    }
}

2. 注册绑定器

在Fruit类上标记绑定器:

[ModelBinder(BinderType = typeof(FruitModelBinder))]
public class Fruit {}

或者直接在Action参数上指定:

[HttpPost("SomeMethod")]
public IActionResult SomeMethod([ModelBinder(BinderType = typeof(FruitModelBinder))] Fruit fruit)
{
    // 原有逻辑不变
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.02 01:18:11