在ASP.NET 5 MVC 6中组合ViewComponents

时间:2015-09-08 22:25:53

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

我试图从控制器中组合多个不同的ViewComponents。所有组合视图组件的ActionResult将呈现给浏览器。 这是基于一篇文章,它使用PartialViews执行此操作并使用ajax更新PartialViews。该文基于以前版本的MVC。有关详细信息,请参阅:https://www.simple-talk.com/dotnet/asp.net/revisiting-partial-view-rendering-in-asp.net-mvc/

几个小时后,我来到下面的代码示例。但问题是它只适用于第一个viewComponent。当我改变v​​iewcomponents的顺序时,它仍然呈现第一个。因此,我的viewcomponents似乎没有任何东西。始终在第二个循环结束于" vc.ExecuteResultAsync(context);"没有错误。所以渲染第一个总是成功的。

顺便说一下,我使用VS 2015企业版和MVC6的Beta7以及所有其他依赖项。

请帮忙!

    public async Task<IActionResult> Dashboard()
    {
        // Combine multiple viewcomponents
        return new MultipleViewResult(
            ViewComponent(typeof(OrdersViewComponent))
            , ViewComponent(typeof(AccountsViewComponent))
            );
    }

    public class MultipleViewResult : ActionResult
    {
    public const string ChunkSeparator = "---|||---";
    public IList<ViewComponentResult> ViewComponentResults { get; private set; }
    public MultipleViewResult(params ViewComponentResult[] views)
    {
        if (ViewComponentResults == null)
        {
            ViewComponentResults = new List<ViewComponentResult>();
        }

        foreach (var v in views)
            ViewComponentResults.Add(v);
    }

    public override async Task ExecuteResultAsync(ActionContext context)
    {
        if (context == null)
            throw new ArgumentNullException(nameof(context));

        byte[] chunkSeparatorBytes = System.Text.Encoding.UTF8.GetBytes(ChunkSeparator);
        var total = ViewComponentResults.Count;
        for (var index = 0; index < total; index++)
        {
            var vc = ViewComponentResults[index];

            // No matter which viewcomponent, this line works only with the first viewcomponent.
            await vc.ExecuteResultAsync(context);

            if (index < total - 1)
            {
                await context.HttpContext.Response.Body.WriteAsync(chunkSeparatorBytes, 0, chunkSeparatorBytes.Length);
            }
        }
    }
}

1 个答案:

答案 0 :(得分:0)

此操作失败,因为第一个vc.ExecuteResultAsync(context)将设置ContentType属性,刷新响应。对vc.ExecuteResultAsync(context)的任何后续调用也将尝试设置ContentType属性,但会失败,因为响应已经流回客户端。

除了创建自己的HttpContext实例之外,我无法想到任何更好的解决方法,即使部分响应已经被发送回来,也会允许您写入ContentType属性,但这很麻烦

如果您认为这是一个错误(我个人认为这是因为ViewComponentResult应该在设置ContentType之前检查响应是否已经发送),那么您始终可以submit a bug report