如何为HTML标题属性设计InfoHelper [英] How to design InfoHelper for html title attribute

查看:64
本文介绍了如何为HTML标题属性设计InfoHelper的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对于Asp.net mvc核心应用程序:在我的一个dbcontext表中,我有一些带有HelpInfo的记录(id为主键,并且为helpInfo的字符串),这些记录要用作我的剃刀视图中的html标题属性,例如:

For Asp.net mvc core app: In one of my dbcontext tables I have records with HelpInfo (id as primary key, and string for helpInfo) that I want to use as html title attributes in my razor views, such as:

< div title ='@ I(12)'></div>

其中12是HelpInfo记录的示例ID,@ I应该是可获取相应helpInfo字符串的全局可访问类方法.

Where 12 is an example id of a HelpInfo record and @I should be a global accessible class method that fetches the corresponding helpInfo string.

我尝试实施King Kings方法,例如:

I tried to implement King Kings approach such as:

CustomView :

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>

In _ViewImports.cshtml I added @inherits CustomView<TModel>

在视图中,我使用了< div title ='@(await I(12))'> Test</div>

加载视图时,我得到

No service for type '...Models.IInfo' has been registered

任何帮助解决该问题的方法将不胜感激.

Any help to pin down the problem would be appreciated.

推荐答案

据我了解,您想要的是 @Html @Url 之类的东西,默认的 Page RazorPage .这只是基础页面公开的自定义属性.因此,在您的情况下,您需要一个自定义视图(对于mvc)或一个自定义页面(对于剃须刀页面).这是用于MVC的自定义视图的示例:

As I understand looks like you want something like @Html or @Url which are supported in the default Page and RazorPage. That's just a custom property exposed by the base page. So in your case, you need a custom view (for mvc) or a custom page (for razor pages). Here is an example of a custom view used for MVC:

public abstract class CustomView<TModel> : RazorPage<TModel>
{              
    //custom members can be declared in here
}

根据您对 I 的期望用法,它必须是一种方法.因此,这可能是基础页面中注入的某些服务公开的方法.假设该接口是这样的:

Based on your desired usage of I, it must be a method. So it can be a method exposed by some service injected in your base page. Suppose that interface is like this:

public interface IInfo {
     string Get(int code);
}

现在,您的自定义页面可以实现如下的 I 方法:

Now your custom page can implement the I method like this:

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 :

To use your custom view, you need to use the directive @inherits in your view or better in the _ViewImports.cshtml so that you don't have to repeat that @inherits everywhere, like this:

@inherits CustomView<TModel>

有时,直到您重建项目后,基本视图才被应用(因此基本成员不可用).

Sometimes the base view is not applied (so the base members are not available) until you rebuild your project.

现在,您可以根据需要在视图中使用 I ,如下所示:

Now you can use the I in your views as what you desire, like this:

<div title="@I(12)"></div>

请注意,在我的示例中, I 方法返回了 string ,也可以使其返回 IHtmlContent (例如: HtmlString)或您需要的任何类型.

Note the I method returns a string in my example, you can also make it return an IHtmlContent (e.g: HtmlString) or whatever type you need for your requirement.

注意:

从技术上讲,您可以使用任何服务(包括从数据库查询数据的服务),但是在这种情况下,请确保查询速度尽可能快,并使用 async 获得最佳性能.避免线程饥饿.以下是从数据库查询的 IInfo 服务的示例:

Technically you can use any services (including ones querying for data from database), but in such cases please ensure that the querying is as fast as possible and use async to have the best performance & avoid thread starvation. Here is an example of the IInfo service that queries from a database:

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 方法,您可以在视图中像这样调用它:

I hope that you know how to register a DbContext to use in your code (that's part of EFCore so you may have to learn more about that first). Now to use the async method, you call it in your view like this:

<div title="@(await I(12))"></div>

同样,我会尽量避免在这样的助手中查询数据库.正如我所说,可以在同一视图中多次调用助手的方法,因此通常我们使用快速方法或将 缓存 用于所需的信息.这与另一个称为 caching 的功能有关,您可以在一个简短的答案中添加更多功能.

Again, I would try to avoid querying the db in such a helper like that. As I said, the helper's method can be called multiple times right in one same view so usually we have fast methods or use caching for the info it need. This is related to another feature called caching which has more to be put in one short answer, you can learn more about that.

这篇关于如何为HTML标题属性设计InfoHelper的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆