【发布时间】:2017-05-10 20:34:06
【问题描述】:
我正在为 MVC .NET Core Web 应用程序使用最新的 VS.2017 更新和模板。我决定要在外部程序集中使用 ViewComponents,因为我阅读了几篇文章,表明如果没有奇怪的技巧,这是不可能的。
我有我的主 Web 应用程序,然后我创建了一个名为 MySite.Components 的 .NET Framework 类库,它是“外部程序集”。我在其中安装了 ViewFeatures NuGet。我在 /Views/Shared/Components/GoogleAdsense/Default.cshtml 中创建了我的 View 组件 CSHTML。
我注意到我的 CSPROJ 已经将 GoogleAdSense 作为嵌入式资源:
<ItemGroup>
<None Include="app.config" />
<None Include="packages.config" />
<EmbeddedResource Include="Views\Shared\Components\GoogleAdsense\Default.cshtml" />
</ItemGroup>
视图组件其实很简单:
namespace MySite.Components.ViewComponents {
[ViewComponent(Name = "GoogleAdsense")]
public class GoogleAdsense : ViewComponent {
public async Task<IViewComponentResult> InvokeAsync(string adSlot, string clientId, string adStyle = "")
{
var model = await GetConfigAsync(adSlot, clientId, adStyle);
return View(model);
}
private Task<GoogleAdUnitCompModel> GetConfigAsync(string adSlot, string clientId, string adStyle)
{
GoogleAdUnitCompModel model = new GoogleAdUnitCompModel
{
ClientId = clientId, // apparently we can't access App_Data because there is no AppDomain in .NET core
SlotNr = adSlot,
Style = adStyle
};
return Task.FromResult(model);
}
}
}
然后在主项目(ASP.NET Core Web 应用程序)中,我安装了 File Provider NuGet 并修改了我的 Startup:
services.Configure<RazorViewEngineOptions>(options =>
{
options.FileProviders.Add(new EmbeddedFileProvider(
typeof(MySite.Components.ViewComponents.GoogleAdsense).GetTypeInfo().Assembly,
"MySite.Components.ViewComponents"
));
});
然后我尝试在这样的视图中使用视图组件:
@using MySite.Components.ViewComponents
:
@Component.InvokeAsync(nameof(GoogleAdsense), new { adSlot = "2700000000", clientId = "ca-pub-0000000000000000", adStyle="" })
我得到一个错误提示
*InvalidOperationException: A view component named 'GoogleAdsense' could not be found.*
还尝试使用不带 nameof() 的表示法,它使用 InvokeAsync 的通用参数,但也失败了,但使用
*"Argument 1: cannot convert from 'method group' to 'object'"*
而使用 TagHelper 表单只会将其呈现为无法识别的 HTML:
<vc:GoogleAdsense adSlot = "2700000000" clientId = "ca-pub-0000000000000000"></vc:GoogleAdsense>
最后,在主程序集(实际的 Web 应用程序)上,我在外部程序集类型上使用了 GetManifestResourceNames() 来验证它是否已嵌入,并且返回的列表将其列为:
[0] = "MySite.Components.Views.Shared.Components.GoogleAdsense.Default.cshtml"
【问题讨论】:
标签: asp.net-core asp.net-core-mvc asp.net-core-viewcomponent