MVC 6/vNext中的HttpResponse.Filter? [英] HttpResponse.Filter in MVC 6 / vNext?
问题描述
我正在研究一个网站框架,该框架使用小部件"在门户网站/门户类型的网站内部呈现内容块.基本上是Wordpress如何让您自定义网站的缩写形式.
I'm working on a website framework that uses "Widgets" to render content chunks inside of a portal/portlet type website. Basically a very abbreviated version of how Wordpress lets you customize a website.
经过搜索并没有找到任何现有框架,看来实现这一目标的最合理方法是使用MVC的部分视图"功能.
Having searched and failed at finding any existing frameworks, it seems like the most reasonable way to implement this is to use the "Partial Views" feature of MVC.
我希望能够完全封装每个小部件",而不必在主机View中重复脚本或样式标签(View不需要了解有关如何呈现Widget的任何知识).
I'd like to be able to fully encapsulate each "widget" without having to repeat script or style tags in the host View (Views shouldn't need to know anything about how to render the Widgets).
要完成此任务,所有脚本引用都由Widget部分视图存储,然后在该视图呈现其自己的脚本部分时注入.在一个实例中,这是使用响应过滤器实现的.
To accomplish this, any script references are stored by the Widget Partial View and later injected when the View renders its own script section. In one instance, this was implemented using a response filter.
我正在通过CoreCLR使用MVC 6(vNext),并试图确定如何在新框架下实现此过滤器位.似乎HttpResponse对象不再具有过滤器"字段.
I'm using MVC 6 (vNext) via CoreCLR and am trying to determine how to implement this filter bit under the new framework. It seems like the HttpResponse object no longer has a "Filter" field.
您能告诉我在新框架下这可能如何工作吗?
Can you tell me how this might work under the new framework?
/// <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);
}
}
}
Original code came from Ryan Burnham's Blog at https://rburnham.wordpress.com/2015/03/13/asp-net-mvc-defining-scripts-in-partial-views/#comment-2286
推荐答案
您可以通过在Startup.cs
中使用Middleware
来实现:
You can accomplish that by using Middleware
in 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?}");
});
}
这篇关于MVC 6/vNext中的HttpResponse.Filter?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!