如何为 html title 属性设计 InfoHelper
How to design InfoHelper for html title attribute
对于 Asp.net mvc 核心应用程序:
在我的一个 dbcontext 表中,我有 HelpInfo 的记录(id 作为主键,helpInfo 的字符串),我想在我的 razor 视图中用作 html 标题属性,例如:
<div title='@I(12)'></div>
其中 12 是 HelpInfo 记录的示例 ID,@I 应该是全局可访问的 class 方法,用于获取相应的 helpInfo 字符串。
我尝试实施 King Kings 方法,例如:
自定义视图:
public abstract class CustomView<TModel> : RazorPage<TModel>
{
protected IInfo Info => Context.RequestServices.GetRequiredService<IInfo>();
public Task<string> I(int code)
{
return Info.GetAsync(code);
}
}
接口:
public interface IInfo
{
Task<string> GetAsync(int code);
}
服务:
public class Info : IInfo
{
private readonly ApplicationDbContext context;
public Info(ApplicationDbContext context)
{
this.context = context;
}
public async Task<string> GetAsync(int code)
{
var myRecord = await context.MyRecords.FindAsync(code);
if (myRecord != null)
{
return myRecord.Info;
}
return null;
}
}
在_ViewImports.cshtml中我添加了@inherits CustomView<TModel>
在视图中我使用了<div title='@(await I(12))'>Test</div>
当我加载视图时,我得到
No service for type '...Models.IInfo' has been registered
如能帮助解决问题,我们将不胜感激。
据我了解,您似乎想要 @Html
或 @Url
之类的东西,它们在默认 Page
和 RazorPage
中受支持。这只是基本页面公开的自定义 属性。因此,在您的情况下,您需要一个自定义视图(对于 mvc)或一个自定义页面(对于 razor 页面)。这是用于 MVC 的自定义视图的示例:
public abstract class CustomView<TModel> : RazorPage<TModel>
{
//custom members can be declared in here
}
根据您希望使用的 I
,它必须是一个方法。所以它可以是在您的基本页面中注入的某些服务公开的方法。假设界面是这样的:
public interface IInfo {
string Get(int code);
}
现在您的自定义页面可以像这样实现 I
方法:
public abstract class CustomView<TModel> : RazorPage<TModel>
{
//NOTE: the custom page class does not support constructor injection
//So we need to get the injected services via the Context like this.
protected IInfo Info => Context.RequestServices.GetRequiredService<IInfo>();
public string I(int code){
return Info.Get(code);
}
}
要使用您的自定义视图,您需要在视图中使用指令 @inherits
或在 _ViewImports.cshtml
中使用更好的指令,这样您就不必在任何地方重复 @inherits
,像这样:
@inherits CustomView<TModel>
有时在重建项目之前不会应用基础视图(因此基础成员不可用)。
现在您可以根据需要在视图中使用 I
,如下所示:
<div title="@I(12)"></div>
注意在我的示例中 I
方法 return 是 string
,您也可以将其设为 return 和 IHtmlContent
(例如:HtmlString
) 或您需要的任何类型。
注意:
从技术上讲,您可以使用任何服务(包括从数据库查询数据的服务),但在这种情况下,请确保查询速度尽可能快,并使用 async
以获得最佳性能并避免线程饥饿。这是从数据库查询的 IInfo
服务的示例:
public interface IInfo {
Task<string> GetAsync(int code);
}
public class Info : IInfo {
//inject whatever your Info needs
//here we just need some DbContext (used in EFCore)
public Info(InfoDbContext dbContext){
_infoDbContext = dbContext;
}
readonly InfoDbContext _infoDbContext;
public async Task<string> GetAsync(int code){
var info = await _infoDbContext....
return info;
}
}
I
方法也应该是 async
:
public Task<string> I(int code){
return Info.GetAsync(code);
}
我希望您知道如何注册 DbContext
以在您的代码中使用(这是 EFCore
的一部分,因此您可能需要先了解更多相关信息)。现在要使用 async
方法,您可以在视图中这样调用它:
<div title="@(await I(12))"></div>
同样,我会尽量避免在这样的助手中查询数据库。正如我所说,助手的方法可以在同一个视图中多次调用,所以通常我们有快速方法或使用 caching 来获取信息需要。这与另一个名为 caching
的功能有关,该功能在一个简短的答案中包含更多内容,您可以了解更多信息。
解决方法:
我的 Startup.cs 添加了:
services.AddScoped<IInfo, Info>();
services.AddTransient<IInfo, Info>();
也有效。
对于 Asp.net mvc 核心应用程序: 在我的一个 dbcontext 表中,我有 HelpInfo 的记录(id 作为主键,helpInfo 的字符串),我想在我的 razor 视图中用作 html 标题属性,例如:
<div title='@I(12)'></div>
其中 12 是 HelpInfo 记录的示例 ID,@I 应该是全局可访问的 class 方法,用于获取相应的 helpInfo 字符串。
我尝试实施 King Kings 方法,例如:
自定义视图:
public abstract class CustomView<TModel> : RazorPage<TModel>
{
protected IInfo Info => Context.RequestServices.GetRequiredService<IInfo>();
public Task<string> I(int code)
{
return Info.GetAsync(code);
}
}
接口:
public interface IInfo
{
Task<string> GetAsync(int code);
}
服务:
public class Info : IInfo
{
private readonly ApplicationDbContext context;
public Info(ApplicationDbContext context)
{
this.context = context;
}
public async Task<string> GetAsync(int code)
{
var myRecord = await context.MyRecords.FindAsync(code);
if (myRecord != null)
{
return myRecord.Info;
}
return null;
}
}
在_ViewImports.cshtml中我添加了@inherits CustomView<TModel>
在视图中我使用了<div title='@(await I(12))'>Test</div>
当我加载视图时,我得到
No service for type '...Models.IInfo' has been registered
如能帮助解决问题,我们将不胜感激。
据我了解,您似乎想要 @Html
或 @Url
之类的东西,它们在默认 Page
和 RazorPage
中受支持。这只是基本页面公开的自定义 属性。因此,在您的情况下,您需要一个自定义视图(对于 mvc)或一个自定义页面(对于 razor 页面)。这是用于 MVC 的自定义视图的示例:
public abstract class CustomView<TModel> : RazorPage<TModel>
{
//custom members can be declared in here
}
根据您希望使用的 I
,它必须是一个方法。所以它可以是在您的基本页面中注入的某些服务公开的方法。假设界面是这样的:
public interface IInfo {
string Get(int code);
}
现在您的自定义页面可以像这样实现 I
方法:
public abstract class CustomView<TModel> : RazorPage<TModel>
{
//NOTE: the custom page class does not support constructor injection
//So we need to get the injected services via the Context like this.
protected IInfo Info => Context.RequestServices.GetRequiredService<IInfo>();
public string I(int code){
return Info.Get(code);
}
}
要使用您的自定义视图,您需要在视图中使用指令 @inherits
或在 _ViewImports.cshtml
中使用更好的指令,这样您就不必在任何地方重复 @inherits
,像这样:
@inherits CustomView<TModel>
有时在重建项目之前不会应用基础视图(因此基础成员不可用)。
现在您可以根据需要在视图中使用 I
,如下所示:
<div title="@I(12)"></div>
注意在我的示例中 I
方法 return 是 string
,您也可以将其设为 return 和 IHtmlContent
(例如:HtmlString
) 或您需要的任何类型。
注意:
从技术上讲,您可以使用任何服务(包括从数据库查询数据的服务),但在这种情况下,请确保查询速度尽可能快,并使用 async
以获得最佳性能并避免线程饥饿。这是从数据库查询的 IInfo
服务的示例:
public interface IInfo {
Task<string> GetAsync(int code);
}
public class Info : IInfo {
//inject whatever your Info needs
//here we just need some DbContext (used in EFCore)
public Info(InfoDbContext dbContext){
_infoDbContext = dbContext;
}
readonly InfoDbContext _infoDbContext;
public async Task<string> GetAsync(int code){
var info = await _infoDbContext....
return info;
}
}
I
方法也应该是 async
:
public Task<string> I(int code){
return Info.GetAsync(code);
}
我希望您知道如何注册 DbContext
以在您的代码中使用(这是 EFCore
的一部分,因此您可能需要先了解更多相关信息)。现在要使用 async
方法,您可以在视图中这样调用它:
<div title="@(await I(12))"></div>
同样,我会尽量避免在这样的助手中查询数据库。正如我所说,助手的方法可以在同一个视图中多次调用,所以通常我们有快速方法或使用 caching 来获取信息需要。这与另一个名为 caching
的功能有关,该功能在一个简短的答案中包含更多内容,您可以了解更多信息。
解决方法:
我的 Startup.cs 添加了:
services.AddScoped<IInfo, Info>();
services.AddTransient<IInfo, Info>();
也有效。