[英]How to design InfoHelper for html title attribute
对于 Asp.net mvc 核心应用程序:在我的一个 dbcontext 表中,我有带有 HelpInfo 的记录(id 作为主键,字符串用于 helpInfo),我想在我的 Z60C05C632A2822A0A843EZ 视图中用作 html 标题属性,例如:
<div title='@I(12)'></div>
其中 12 是 HelpInfo 记录的示例 ID,@I 应该是获取相应 helpInfo 字符串的全局可访问 class 方法。
我尝试实施 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
任何有助于确定问题的帮助将不胜感激。
据我了解,您似乎想要默认Page
和RazorPage
支持的@Html
或@Url
之类的东西。 这只是基本页面公开的自定义属性。 因此,在您的情况下,您需要自定义视图(用于 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
方法返回一个string
,您也可以让它返回一个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
的功能有关,该功能需要在一个简短的答案中提供更多信息,您可以了解更多信息。
解决方案:
在我的 Startup.cs 中,我添加了:
services.AddScoped<IInfo, Info>();
services.AddTransient<IInfo, Info>();
也确实有效。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.