【问题标题】:HttpResponse.Filter in MVC 6 / vNext?MVC 6 / vNext 中的 HttpResponse.Filter?
【发布时间】:2015-11-18 01:47:38
【问题描述】:

我正在开发一个网站框架,该框架使用“小部件”在门户/portlet 类型的网站内呈现内容块。基本上是 Wordpress 如何让您自定义网站的一个非常简略的版本。

搜索并未能找到任何现有框架,似乎最合理的实现方式是使用 MVC 的“部分视图”功能。

我希望能够完全封装每个“小部件”,而不必在宿主视图中重复脚本或样式标签(视图不需要知道如何呈现小部件)。

为了实现这一点,任何脚本引用都由 Widget 部分视图存储,然后在视图呈现自己的脚本部分时注入。在一种情况下,这是使用响应过滤器实现的。

我正在通过 CoreCLR 使用 MVC 6 (vNext),并试图确定如何在新框架下实现此过滤器位。看起来 HttpResponse 对象不再有“过滤器”字段。

你能告诉我这在新框架下如何工作吗?

/// <summary>
/// Appends partial view scripts to the html response of an AJAX request
/// </summary>
public class RenderAjaxPartialScriptsAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        if (filterContext.HttpContext.Request.IsAjaxRequest())
        {
            var response = filterContext.HttpContext.Response;
            if (response.Filter != null)
            response.Filter = new RenderAjaxPartialScriptsResponseFilter(response.Filter, filterContext);
        }
    }
}

原始代码来自 Ryan Burnham 的博客https://rburnham.wordpress.com/2015/03/13/asp-net-mvc-defining-scripts-in-partial-views/#comment-2286

【问题讨论】:

    标签: asp.net-mvc asp.net-core asp.net-core-mvc


    【解决方案1】:

    您可以通过在Startup.cs 中使用Middleware 来实现:

    快捷方式:

    public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
        {
            //// 
    
            app.Use(async (httpContext, next) =>
            {
                await next();
    
                // if is ajax request
                if (httpContext.Request.Headers["X-Requested-With"] == "XMLHttpRequest")
                {
                    // if succesful status code
                    if (httpContext.Response.StatusCode == 200)
                    {
                        // you can get scripts data from httpContext.Items[key] and build html
                        string html = "<script src='~/js/script-demo.js'></script>";
    
                        using (var writeResponseStream = new StreamWriter(httpContext.Response.Body))
                        {
                            // write html to response body
                            await writeResponseStream.WriteAsync(html);
                        }
                    }
                }
            });
    
            // Add MVC to the request pipeline.
            app.UseMvc(routes =>
            {
                routes.MapRoute(
                    name: "default",
                    template: "{controller=Home}/{action=Index}/{id?}");
            });
        }
    

    正确的方法:

    中间件实现:

        public class AjaxScriptInjectorMiddleware
        {
            private readonly RequestDelegate _next;
    
            public AjaxScriptInjectorMiddleware(RequestDelegate next)
            {
                    _next = next;
            }
    
            public async Task Invoke(HttpContext context)
            {
                await _next.Invoke(context);
    
                // if is ajax request
                if (IsAjax(context.Request))
                {
                    // if succesful status code
                    if (IsSuccess(context.Response.StatusCode))
                    {
                        // you can get scripts data from context.Items[key] and build html
                        string html = "<script src='~/js/script-demo.js'></script>";
    
                        using(var writeResponseStream = new StreamWriter(context.Response.Body))
                        {
                            // write html to response body
                            await writeResponseStream.WriteAsync(html);
                        }
                    }
                }
            }
    
            private bool IsAjax(HttpRequest request)
            {
                    return request.Headers["X-Requested-With"] == "XMLHttpRequest";
            }
    
            private bool IsSuccess(int statusCode)
            {
                    return statusCode >= 200 && statusCode <= 299;
            }
       }
    

    IApplicationBuilder扩展方法:

    public static class AjaxScriptInjectorExtensions
    {
        public static IApplicationBuilder UseAjaxScriptInjector(this IApplicationBuilder builder)
        {
                return builder.UseMiddleware<AjaxScriptInjectorMiddleware>();
        }
    }
    

    使用middleware

    public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
    {
         // use custom ajax script injector middleware
         app.UseAjaxScriptInjector();
    
         // Add MVC to the request pipeline.
         app.UseMvc(routes =>
         {
              routes.MapRoute(
                   name: "default",
                   template: "{controller=Home}/{action=Index}/{id?}");
              });
         }
    

    【讨论】:

    • 哇。这是更多的工作!感谢您为我解决这个问题。
    猜你喜欢
    • 1970-01-01
    • 2017-01-01
    • 1970-01-01
    • 2015-04-07
    • 2014-12-14
    • 1970-01-01
    • 2016-09-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多