2015-09-08 57 views
1

我試圖從一個控制器組合多個不同的ViewComponents。所有組合viewcomponents的ActionResult將呈現給瀏覽器。 這是基於一篇關於PartialViews的文章,並用ajax更新PartialViews。該文章基於以前版本的MVC。欲瞭解更多信息,請參閱:https://www.simple-talk.com/dotnet/asp.net/revisiting-partial-view-rendering-in-asp.net-mvc/在ASP.NET 5中組合ViewComponents MVC 6

幾個小時後,我來到下面的代碼示例。但問題是,它只適用於第一個viewComponent。當我改變v​​iewcomponents的順序時,它仍然呈現第一個。所以它對我的視圖組件似乎沒有任何影響。總是在第二個循環處結束於「vc.ExecuteResultAsync(context);」沒有錯誤。所以渲染第一個總是成功的。

順便說一句,我使用MVC6 Beta7和其他所有依賴的VS 2015 Enterprise。

請幫忙!

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); 
      } 
     } 
    } 
} 
+0

我想你可能會在每次執行ExecuteResultAsync時覆蓋響應體。不知道,但。查看此鏈接以查看幕後發生的情況:https://github.com/aspnet/Mvc/commit/e91ce4560f46b0bbcd1e5e3b4430e2291b408c54?diff=unified#diff-707effa79d34b01ef21df4ecf89e9497R66 – mbudnik

回答

0

失敗的原因是第一vc.ExecuteResultAsync(context)將設置ContentType財產和沖洗的響應。任何後續撥打vc.ExecuteResultAsync(context)也將嘗試設置ContentType屬性,但會失敗,因爲響應已被傳輸回客戶端。

我想不出任何更好的解決方法,除了創建自己的HttpContext實例,即使響應的一部分已經被髮送回來但是這很混亂,您可以寫入ContentType屬性。

如果您認爲這是一個錯誤(我個人認爲這是因爲ViewComponentResult應該檢查在設置ContentType之前是否已經發送了響應),那麼您總是可以使用submit a bug report

+0

第一次將context.HttpContext.Response.HasStarted從「false 「到」真「。我認爲這意味着響應被刷新並且ContentType不能再被設置。可能是因爲「HasStarted」屬性。 – user2375542

+0

你是對的。在設置ContentType之前應該檢查該屬性。我看到你(或某人)已經提交了[bug報告](https://github.com/aspnet/Mvc/issues/3111)。 – Dealdiane