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

ASP.NET Core 8 MVC中用Avro字节传输替代JSON的视图适配问题

问题解决方案

一、先纠正核心误解

MVC控制器到视图的模型传递是服务器内存内的对象直接传递,不存在HTTP层面的序列化传输(那是Web API的场景)。你当前把PersonDTO序列化成byte[]再传给View(),本质是类型不匹配导致的错误——视图期望PersonDTO,但你传了字节数组。

如果确实需要通过Avro序列化传递(比如特殊业务场景),可以按以下两种方式处理:

方案1:视图内直接反序列化

控制器端

把序列化后的字节数组存入ViewData或包装成ViewModel:

// 方式A:用ViewData传递
byte[] avroBytes = AvroConvert.Serialize(person, CodecType.Brotli);
ViewData["AvroPersonData"] = avroBytes;
return View();

// 方式B:用包装类作为视图模型
public class AvroWrapperViewModel
{
    public byte[] AvroData { get; set; }
}

// 控制器返回包装类
return View(new AvroWrapperViewModel { AvroData = avroBytes });

视图端

在Razor视图中反序列化字节数组得到目标模型:

@* 对应方式A:从ViewData取数据 *@
@{
    var avroBytes = ViewData["AvroPersonData"] as byte[];
    var person = AvroConvert.Deserialize<PersonDTO>(avroBytes, CodecType.Brotli);
}

<div>姓名:@person.Name</div>

@* 对应方式B:用包装类作为模型 *@
@model AvroWrapperViewModel
@{
    var person = AvroConvert.Deserialize<PersonDTO>(Model.AvroData, CodecType.Brotli);
}

<div>年龄:@person.Age</div>

二、自定义RazorPage<T>的统一处理方案

如果想全局统一处理Avro反序列化,不需要重写ExecuteAsync(那是页面执行的核心逻辑,风险高),可以重写页面生命周期钩子来完成反序列化:

1. 自定义抽象RazorPage类

public abstract class CustomAvroRazorPage<TModel> : RazorPage<TModel>
{
    public override async Task<IActionResult> OnPageHandlerExecutionAsync(PageHandlerExecutingContext context, PageHandlerExecutionDelegate next)
    {
        // 从ViewData读取预先存入的Avro字节数组
        if (ViewData.TryGetValue("AvroModelData", out var avroObj) && avroObj is byte[] avroBytes)
        {
            // 反序列化得到目标模型并赋值给ViewData.Model
            var model = AvroConvert.Deserialize<TModel>(avroBytes, CodecType.Brotli);
            ViewData.Model = model;
        }
        return await next();
    }
}

2. 视图指定继承自定义类

在.cshtml顶部替换默认的继承关系:

@inherits CustomAvroRazorPage<PersonDTO>

<!-- 此时Model已自动反序列化为PersonDTO -->
<div>@Model.Name | @Model.Age</div>

3. 控制器传递Avro字节

byte[] avroBytes = AvroConvert.Serialize(person, CodecType.Brotli);
ViewData["AvroModelData"] = avroBytes;
return View();

三、更合理的替代建议

如果你的目标是减少HTTP传输开销,那应该用ASP.NET Core Web API而非MVC视图:

  • API控制器返回Avro字节流:
[HttpGet("person")]
public IActionResult GetPerson()
{
    var person = new PersonDTO { Name = "张三", Age = 30 };
    byte[] avroBytes = AvroConvert.Serialize(person, CodecType.Brotli);
    return File(avroBytes, "application/avro");
}
  • 前端用Avro库反序列化字节流即可。

如果是MVC服务器端渲染场景,完全没必要序列化模型——直接传递PersonDTO对象给return View(person),服务器内部传递无HTTP开销,性能更优。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 17:32:44