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

Asp.net Core 3.1 SSE EventSource返回MIME类型错误问题咨询

问题根因

该错误是代码逻辑不兼容ASP.NET Core 运行环境导致的,无需修改Startup.cs默认配置即可解决:
你当前使用的是ASP.NET Framework 时代的SSE写法,ASP.NET Core 中[ApiController]特性会自动将控制器方法的返回值序列化为JSON,直接返回HttpResponseMessage类型时,框架不会将其识别为原生HTTP响应,反而会把整个对象序列化为JSON结构,导致响应头的Content-Type被自动设置为application/json,你代码里配置的text/event-stream完全不生效。同时PushStreamContent类本身不属于ASP.NET Core 原生类库,写法不适配当前环境。

修正方案

1. 重写SSE订阅接口

直接操作当前请求的HttpContext响应对象,手动配置SSE所需的响应头:

[ApiController]
[Route("/SSE/[action]")]
public class SSEController : Controller
{
    private static ConcurrentBag<StreamWriter> clients = new ConcurrentBag<StreamWriter>();
    
    [HttpPost]
    public async Task SSECallbackMsg()
    {
        await CallbackMsg("test");
    }
    
    private async Task CallbackMsg(string content)
    {
        // SSE消息必须符合格式:data: {内容}\n\n,否则前端EventSource无法触发message事件
        var sseMessage = $"data: {content}\n\n";
        var invalidClients = new List<StreamWriter>();
        
        foreach (var client in clients)
        {
            try
            {
                if (client.BaseStream.CanWrite)
                {
                    await client.WriteAsync(sseMessage);
                    await client.FlushAsync();
                    // 如果不需要保持长连接,单次推送后可以释放,否则不要执行Dispose
                    // client.Dispose();
                    // invalidClients.Add(client);
                }
                else
                {
                    invalidClients.Add(client);
                }
            }
            catch (Exception)
            {
                invalidClients.Add(client);
            }
        }
        
        // 清理失效客户端
        foreach (var invalidClient in invalidClients)
        {
            clients.TryTake(out _);
            invalidClient.Dispose();
        }
    }
    
    [HttpGet]
    public async Task GETSubscibe()
    {
        // 配置SSE所需响应头
        Response.Headers.Add("Content-Type", "text/event-stream");
        Response.Headers.Add("Cache-Control", "no-cache");
        Response.Headers.Add("Connection", "keep-alive");
        
        await Response.Body.FlushAsync();
        
        // 把当前客户端加入连接池
        var clientWriter = new StreamWriter(Response.Body, Encoding.UTF8);
        clients.Add(clientWriter);
        
        // 保持长连接不返回,直到连接断开
        await Task.Delay(Timeout.Infinite, HttpContext.RequestAborted);
    }
}

2. 可选跨域配置

如果前端页面和服务端地址端口不一致,需要在Startup.cs中添加CORS配置允许跨域请求:

  • 在ConfigureServices方法中添加:
services.AddCors(options =>
{
    options.AddPolicy("AllowSSE", policy =>
    {
        policy.AllowAnyHeader()
              .AllowAnyMethod()
              .AllowCredentials()
              .WithOrigins("你的前端地址,比如http://localhost:8080");
    });
});
  • 在Configure方法中,UseRouting之后、UseAuthorization之前添加:
app.UseCors("AllowSSE");
其他注意事项
  • SSE的消息格式必须严格遵循data: 消息内容\n\n的规范,缺少前缀或换行符都会导致前端无法正常接收消息
  • 原代码中推送完消息立即释放StreamWriter会直接断开长连接,EventSource会按照默认规则自动重连,如果需要持续推送不要主动释放连接对象

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 09:36:04