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

ASP.NET Core如何按TransactionType条件使用多模型实现单端点处理交易

实现方案

步骤1:重构模型结构,抽离公共基类

将三个模型共有的属性提取到抽象基类,三个交易模型分别继承基类,按需扩展自有属性:

// 公共交易请求基类
public abstract class TransactionBaseRequest
{
    public string TransactionType { get; set; }
    public CardDetails CardDetails { get; set; }
}

// 支付请求模型
public class PaymentRequest : TransactionBaseRequest
{
    // 补充支付场景独有属性,例如订单号、支付金额等
    public string OrderNo { get; set; }
    public decimal PayAmount { get; set; }
}

// 退款请求模型
public class RefundRequest : TransactionBaseRequest
{
    // 补充退款场景独有属性,例如原交易号、退款金额等
    public string OriginalTransactionId { get; set; }
    public decimal RefundAmount { get; set; }
}

// 重复交易请求模型
public class RepeatRequest : TransactionBaseRequest
{
    // 补充重复交易场景独有属性,例如原授权码等
    public string OriginalAuthCode { get; set; }
}

步骤2:实现自定义JSON反序列化转换器

ASP.NET Core 6默认使用System.Text.Json做序列化,自定义转换器可以根据TransactionType字段自动反序列化为对应子类对象:

using System.Text.Json;
using System.Text.Json.Serialization;

public class TransactionRequestConverter : JsonConverter<TransactionBaseRequest>
{
    public override TransactionBaseRequest Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        // 先加载JSON节点
        var jsonNode = JsonNode.Parse(ref reader);
        // 读取交易类型字段
        var transactionType = jsonNode["TransactionType"]?.GetValue<string>()?.ToLower();
        if (string.IsNullOrWhiteSpace(transactionType))
        {
            throw new ArgumentException("请求缺少TransactionType参数");
        }

        // 根据交易类型反序列化为对应模型
        return transactionType switch
        {
            "payment" => jsonNode.Deserialize<PaymentRequest>(options),
            "refund" => jsonNode.Deserialize<RefundRequest>(options),
            "repeat" => jsonNode.Deserialize<RepeatRequest>(options),
            _ => throw new NotSupportedException($"不支持的交易类型:{transactionType}")
        };
    }

    public override void Write(Utf8JsonWriter writer, TransactionBaseRequest value, JsonSerializerOptions options)
    {
        // 序列化时按实际类型输出
        JsonSerializer.Serialize(writer, value, value.GetType(), options);
    }
}

步骤3:注册自定义转换器

在Program.cs中把自定义转换器注册到系统JSON配置中:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllers()
    .AddJsonOptions(options =>
    {
        // 注册自定义交易请求转换器
        options.JsonSerializerOptions.Converters.Add(new TransactionRequestConverter());
    });

// 其他服务注册、中间件配置逻辑保持不变
var app = builder.Build();
app.MapControllers();
app.Run();

步骤4:调整控制器逻辑

控制器接口直接用基类作为入参,根据实际类型分发到对应业务逻辑即可:

[HttpPost]
[Route("all-payment")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<IActionResult> HandleTransaction([FromBody] TransactionBaseRequest request)
{
    object result = request switch
    {
        PaymentRequest paymentReq => await _paymentService.ProcessPayment(paymentReq),
        RefundRequest refundReq => await _refundService.ProcessRefund(refundReq),
        RepeatRequest repeatReq => await _repeatService.ProcessRepeat(repeatReq),
        _ => throw new NotSupportedException("不支持的交易类型")
    };
    return Ok(result);
}

如果你项目用的是Newtonsoft.Json而非System.Text.Json,实现思路完全一致,只需继承Newtonsoft的JsonConverter实现对应逻辑即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 06:45:03