asp.net 如何在C# MVC中将变量从一个过滤器传递到一个控制器操作?

pxq42qpu  于 2023-11-20  发布在  .NET
关注(0)|答案(5)|浏览(113)

采用一个简单的操作过滤器,检查用户是否登录并检索他们的用户ID。

public class LoginFilter : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {    
        // Authenticate (somehow) and retrieve the ID
        int id = Authentication.SomeMethod();
        // Pass the ID through to the controller?
        .....
    }
}

字符串
然后我如何将这个ID传递给我的控制器操作?

[LoginFilter]
public class Dashboard : Controller
{
    public ActionResult Index()
    {
        // I'd like to be able to use the ID from the LoginFilter here
        int id = ....
    }
}


有没有一个类似ViewBag的东西可以让我这样做?或者其他一些技术可以让我在过滤器和控制器动作之间传递变量和对象?

voj3qocg

voj3qocg1#

我相信ActionExecutingContext包含一个对调用控制器的引用。使用这个引用和一个从基类Controller派生的自定义控制器类混合,然后将id存储为控制器的示例变量可能就可以了。
自定义控制器

Public Class MyController : Controller
{
    Public int Id {get;set;}
}

字符串
登录过滤器

public class LoginFilter : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {    
        // Authenticate (somehow) and retrieve the ID
        int id = Authentication.SomeMethod();
        ((MyController)filterContext.Controller).Id = id; 
        //Assign the Id by casting the controller (you might want to add a if ... is MyController before casting)
    }
}


控制器

[LoginFilter]
public class Dashboard : MyController
{
    public ActionResult Index()
    {
        //Read the Id here
        int id = this.Id
    }
}

g2ieeal7

g2ieeal72#

你可以这样使用ViewData/ViewBag
1.)使用ViewData

**注意:**在ViewData的情况下,你需要做一个步骤,那就是你必须类型转换它

public class LoginFilter : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {    
        // Authenticate (somehow) and retrieve the ID
        int idValue = Authentication.SomeMethod();

        // Pass the ID through to the controller?
        filterContext.Controller.ViewData.Add("Id", idValue);
    }
}

字符串
然后在控制器功能中

[LoginFilter]
public class Dashboard : Controller
{
    public ActionResult Index()
    {
        // I'd like to be able to use the ID from the LoginFilter here
        int id = (int)ViewData["Id"];
    }
}


2.)使用ViewBag

public class LoginFilter : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {    
        // Authenticate (somehow) and retrieve the ID
        int idValue = Authentication.SomeMethod();

        // Pass the ID through to the controller?

        filterContext.Controller.ViewBag.Id = idValue; 
    }
}


然后在控制器中,

[LoginFilter]
public class Dashboard : Controller
{
    public ActionResult Index()
    {
        // I'd like to be able to use the ID from the LoginFilter here
        int id = ViewBag.Id;
    }
}

x33g5p2x

x33g5p2x3#

您可以通过执行以下操作来使用ViewBag

filterContext.Controller.ViewBag.Id = id;

字符串
这样就可以了,一旦你做了filterContext.Controller,你就可以访问它里面的所有字段,比如TempData
即便如此,如果您使用的是OWIN,那么您可能可以使用Controller.User来获取用户的id,它有一个扩展方法来获取Id,并有属性来获取大多数其他标准数据,如Name等。

fcg9iug3

fcg9iug34#

这是我在一个旧应用程序中看到的一个方法,它避免了使用viewbag,而是让控制器参数指定它们所期望的:

public class LoginFilter : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {    
        // Authenticate (somehow) and retrieve the ID
        int id = Authentication.SomeMethod();
        
        // Check if there's an action parameter on the controller: set it to your ID
        if (filterContext.ActionParameters.ContainsKey("authId"))
        {
            filterContext.ActionParameters["authId"] = id;
        }
    }
}

[LoginFilter]
public class Dashboard : Controller
{
    public ActionResult Index(int authId)
    {
        // authId parameter is available to each action bearing LoginFilter
        // It's instantiated if it's present in the method signature
        ...
    }
}

字符串

umuewwlo

umuewwlo5#

我相信,使用控制器- ViewData或ViewBag是错误的解决方案。
定义一个具有所需属性的小类,并通过服务注册这个类。

public class LittleClass
{
    public string WhatEver {get;set;}
}

字符串
在服务上,

//...
services.AddScoped<LittleClass>();
//..


现在您可以在Filter和Controller上使用依赖注入

public class YourFilter : ActionFilterAttribute
{
    private LittleClass _c;
    public YourFilter(LittleClass c)
    {
        _c = c;
    }
    
    public override void OnActionExecuting(ActionExecutingContext context)
    {
        //manipulate _c
        _c.WhatEver = "TEST";
        base.OnActionExecuting(context);
    }
}


同样的,通过依赖注入你的控制器。

public class YourController : Controller
{

    private LittleClass _c;

    public YourController(LittleClass c)
    {
        _c = c;
        Console.WriteLine( _c.WhatEver ); // => TEST
    }
}

相关问题