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

C#返回JsonResult场景下如何通过ActionFilter注入执行Javascript

方案1:将脚本注入Json返回值,前端触发执行(适配绝大多数场景,无兼容问题)

这个方案不需要修改原有Controller的业务逻辑,只需要调整ActionFilter和前端Ajax回调即可实现需求。

调整ActionFilter代码

在OnActionExecuted方法中直接扩展原有JsonResult的返回结构,追加script字段:

[AttributeUsage(AttributeTargets.Method, Inherited = true, AllowMultiple = false)]
public class InsertJavascriptAttribute : ActionFilterAttribute
{
    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        var jsonResult = filterContext.Result as JsonResult;
        if (jsonResult == null)
        {
            return;
        }
        var script = GenerateMyJavascript();
        
        // 扩展原有Json返回结构,追加script字段
        // 如果用Newtonsoft.Json,直接转JObject追加字段即可
        var jsonObj = Newtonsoft.Json.Linq.JObject.FromObject(jsonResult.Data);
        jsonObj.Add("script", script);
        jsonResult.Data = jsonObj;
    }
}

前端添加脚本执行逻辑

你已经在Ajax.BeginForm中绑定了OnSuccess回调,直接在对应的JS方法中添加脚本执行逻辑即可:

// 你绑定的OnSuccessId对应的JS函数
function yourOnSuccessHandler(response, status, xhr) {
    // 原有业务逻辑,比如渲染partial html、处理错误字段等
    // ...

    // 新增:判断返回值是否带脚本,有就执行
    if (response.script) {
        // 方式1:直接eval执行(适合脚本逻辑和当前上下文关联的场景)
        // eval(response.script);
        // 方式2:创建script标签插入DOM执行(更稳妥,避免上下文冲突)
        const scriptEl = document.createElement('script');
        scriptEl.textContent = response.script;
        document.body.appendChild(scriptEl);
    }
}

如果不想每个Ajax请求都单独加逻辑,可以注册全局Ajax成功事件统一处理所有带script字段的返回:

$(document).ajaxSuccess(function(event, xhr, settings, response) {
    if (response?.script) {
        const scriptEl = document.createElement('script');
        scriptEl.textContent = response.script;
        document.body.appendChild(scriptEl);
    }
});

方案2:脚本放入响应头传递(适合短脚本场景)

如果不想修改原有Json返回结构,且待插入的脚本长度很短,可以把脚本编码后放到自定义响应头中传递:

ActionFilter代码

public override void OnActionExecuted(ActionExecutedContext filterContext)
{
    var jsonResult = filterContext.Result as JsonResult;
    if (jsonResult == null)
    {
        return;
    }
    var script = GenerateMyJavascript();
    // 编码后放入自定义响应头,避免特殊字符报错
    filterContext.HttpContext.Response.Headers.Add("X-Custom-Run-Script", Uri.EscapeDataString(script));
}

前端执行逻辑

function yourOnSuccessHandler(response, status, xhr) {
    // 原有业务逻辑
    // ...

    // 取响应头中的脚本
    const rawScript = xhr.getResponseHeader("X-Custom-Run-Script");
    if (rawScript) {
        const script = decodeURIComponent(rawScript);
        // 执行脚本逻辑和方案1一致
        const scriptEl = document.createElement('script');
        scriptEl.textContent = script;
        document.body.appendChild(scriptEl);
    }
}

注意:该方案受浏览器响应头长度限制,仅适合长度小于1KB的短脚本使用。


内容的提问来源于stack exchange,提问作者M. Chris

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.23 21:54:04