且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

在视图中调用控制器方法

更新时间:2023-02-12 11:41:19

您可以将该逻辑移至单独的类.由于此代码使用的是HttpContext.Session,因此***为您的类创建一个接口,并使用HttpContext.Session将此类作为您的具体实现.您可以在控制器中注入所需的实现,也可以使用依赖关系注入"框架进行查看.

You may move that logic to a separate class. Since this code is using HttpContext.Session, it is a good idea to create an interface for your class and let this class be your concrete implementation using HttpContext.Session. You can inject the needed implementation in your controller or view using the Dependency Injection framework.

public interface IUserAccessHelper
{
    bool IsInRole(string role);
}
public class UserAccessHelper : IUserAccessHelper
{
    private readonly IHttpContextAccessor httpContextAccessor;

    public UserAccessHelper(IHttpContextAccessor httpContextAccessor)
    {
        this.httpContextAccessor = httpContextAccessor;
    }
    public Boolean IsInRole(string role)
    {
        Boolean roleMembership = false;

        if (httpContextAccessor.HttpContext.Session.GetInt32("ID") != null)
        {
            if (httpContextAccessor.HttpContext.Session.GetString("Role") == role)
            {
                roleMembership = true;
            }
        }
        return roleMembership;
    }
}

现在请确保在Startup.cs

services.AddTransient<IUserAccessHelper, UserAccessHelper>();

现在在razor视图中,您可以注入此依赖项.是的,现在可以在视图中使用DI了:)

Now in the razor view, you can inject this dependency. Yes, DI is possible in views now :)

@inject IUserAccessHelper UserAccessHelper
@if (UserAccessHelper.IsInRole("SomeRole"))
{
    <h2>In Role</h2>
}
else
{
    <h2>Not in Role</h2>
 }

您可以通过构造函数注入将相同的IUserAccessHelper注入到控制器中.

You can inject the same IUserAccessHelper inside your controller via constructor injection.

public class HomeController : Controller
{
    private readonly IUserAccessHelper userAccessHelper;
    public HomeController(IUserAccessHelper userAccessHelper) 
    {
        this.userAccessHelper = userAccessHelper;
    }
    public ActionResult Create()
    {
       // you can use this.userAccessHelper.IsInRole("abc")
       // to do  :return something
    }
}

由于要通过依赖关系注入来注入所需的实现,因此现在可以对控制器方法进行单元测试. 您的控制器代码现在与HttpContext没有任何紧密联系.您可以为单元测试创​​建一个MockUserAccessHelper(不使用HttpContext),并根据需要使用它.

Since you are injecting the needed implementation via dependency injection, now you can unit test your controller method. Your controller code does not have any tight coupling to HttpContext now. You can create a MockUserAccessHelper (which does not use HttpContext) for your unit tests and use that as needed.