MVC 6 / vNext中的HttpResponse.Filter?

时间:2015-11-18 01:47:38

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

我正在开发一个使用" Widgets"的网站框架。在门户/ portlet类型的网站内呈现内容块。基本上是Wordpress如何让您自定义网站的缩写版本。

搜索并找不到任何现有框架后,似乎最合理的方法是使用"部分视图" MVC的特色。

我希望能够完全封装每个小部件"无需在主机视图中重复脚本或样式标记(视图不应该知道有关如何呈现窗口小部件的任何信息)。

为实现此目的,任何脚本引用都由Widget部分视图存储,稍后在View呈现其自己的脚本部分时注入。在一个实例中,这是使用响应过滤器实现的。

我通过CoreCLR使用MVC 6(vNext),并试图确定如何在新框架下实现此过滤器位。似乎HttpResponse对象不再具有" Filter"字段。

你能否告诉我这在新框架下如何运作?

/// <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

的博客

1 个答案:

答案 0 :(得分:3)

您可以使用Middleware中的Startup.cs

来实现这一目标

快速方式:

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?}");
          });
     }