我正在尝试使用基本的ASP.NET核心MVC和随附的ViewComponents来尝试一些我不确定的东西。
我很陌生等待,但仍然没有完全掌握这个概念。另外,我也是ASP.NET Core和新的ViewComponents功能的新手。因此,请耐心试图解释我想要实现的目标。
这里的主要目标是将外部端点的HTML异步注入ASP.NET Core MVC站点。
假设我有以下端点可以提供HTML的简单摘要:
http://fragments.mydomain.com/component1 --> Returns <div>Component 1</div> in 1000ms
http://fragments.mydomain.com/component2 --> Returns <div>Component 2</div> in 500ms
请注意,第一个需要 1000毫秒来响应,第二个需要 500毫秒才能响应。
现在,我想在ASP.NET Core MVC的各个部分中注入这些端点的响应。以下是我试图实现这一目标的方法。
首先,我创建了一个从端点吸入HTML的ViewComponents,例如:
public class PieceViewComponent : ViewComponent
{
public async Task<IHtmlContent> InvokeAsync(string pieceUrl)
{
var contentString = "";
try
{
using (var client = new HttpClient())
{
// Make the call to the html end point
contentString = await client.GetStringAsync(url);
// Return the Piece to the caller
return new HtmlString(contentString);
}
}
catch (Exception)
{
// TODO: Handle, log exceptions
return new HtmlString("");
}
}
}
然后,我在视图中调用视图组件,例如 Views / Home / Index.cshtml
<p>Render Component 1 here:<p>
@await Component.InvokeAsync("Piece", new {pieceUrl="http://fragments.mydomain.com/component1"});
<p>Render Component 2 here:<p>
@await Component.InvokeAsync("Piece", new {pieceUrl="http://fragments.mydomain.com/component2"});
正如您所期望的,运行上述内容的结果是:
<p>Render Component 1 here:<p>
<div>Component 1</div>
<p>Render Component 2 here:<p>
<div>Component 2</div>
...但是,结果是以同步方式构建的,返回结果需要1500ms,1000ms + 500ms(endpoint1 + endpoint2)。我想让它在1000毫秒内返回(最慢端点的时间,在这种情况下为endpoint1
所以我在 Views / Home / Index.cshtml 中尝试了以下更改:
@{
var piece1Task = Component.InvokeAsync("Piece", new {pieceUrl="http://fragments.mydomain.com/component1"});
var piece2Task = Component.InvokeAsync("Piece", new {pieceUrl="http://fragments.mydomain.com/component2"});
}
<p>Render Component 1 here:<p>
@await piece1Task
<p>Render Component 2 here:<p>
@await piece1Task
GREAT!结果以1000毫秒返回,这是我希望它返回的理想时间。
....但是,这仅适用于对ComponentInvokeAsync()的所有调用都在同一个View文件中。当您尝试在应用程序中的各种视图周围进行调用时,您最终会再次获得同步结果。例如:
查看/主页/ Index.cshtml:
@{
var piece1Task = Component.InvokeAsync("Piece", new {pieceUrl="http://fragments.mydomain.com/component1"});
}
<p>Render Component 1 here:<p>
@await piece1Task
查看/共享/ _Layout.cshtml:
@{
var piece2Task = Component.InvokeAsync("Piece", new {pieceUrl="http://fragments.mydomain.com/component2"});
}
<html>
....
<p>Render Component 2 here:<p>
@await piece1Task
@RenderBody()
....
</html>
同样,正如您所期望的那样,结果将如下所示:
<html>
...
<p>Render Component 2 here:<p>
<div>Component 2</div>
<p>Render Component 1 here:<p>
<div>Component 1</div>
...
</html>
不幸的是,上述回报时间为1500毫秒。
我可能会以完全错误的方式解决这个问题,但是使用ViewComponents非常方便地将外部HTML部分同步到您的网站应用程序中(就像我上面所说的那样)(特别是在今天的面向服务的世界中)。基本上,响应时间应该是(或大约)最慢外部终点的时间。
如果我可以按照需要使上述工作正常工作,我们可以将其进一步扩展到TagHelpers并具有以下内容:
<piece url="http://fragment.mydomain.com/component1" paramters="..." client-async="true" />
......不会那么好。
例如,当client-async = true时,在客户端而不是服务器上异步加载该段html。
有没有人试图使用ASP.NET MVC Core + ViewComponents做这个或类似的东西,或者我是否想要过于雄心勃勃。
也许其他人已经实现了这一点?
提前致谢,我对这篇长篇文章感到非常抱歉,但我找不到更短的解释方式