2

我是 mvc 的新手,我在控制器的方法中加载 ViewBag,

HomeController: Controller
{
    Public ActionResult Index()
    {
        loadViewBag();
        return View();
    }

    public void loadViewBag()
    {
      ViewBag.aaa = "something";
    }
}

它工作正常。

我的问题是,现在我想从另一个控制器(比如 Account)调用 loadViewBag() 方法,以便我可以重用相同的方法,并且由于一些静态变量需要使 loadViewBag() 方法静态: public static void loadViewBag() 如果我使 loadViewBag 方法静态,ViewBag 上出现错误“非静态字段、方法或属性 'System.Web.Mvc.ControllerBase.ViewBag.get' 需要对象引用”。

是否有任何解决方案/建议。

谢谢你。

4

3 回答 3

10

只需使其成为 ControllerBase 的扩展方法,例如

public static void ControllerExt
{
    public static void LoadViewBag(this ControllerBase controller)
    {
        controller.ViewBag.aaa = "something";
        ...
    }
}

这样你就可以在任何控制器中使用它

public class HomeController : Controller
{
    public ActionResult Index()
    {
        this.LoadViewBag();
        return View();
    }
}

public class AccountController : Controller
{
    public ActionResult Index()
    {
        this.LoadViewBag();
        return View();
    }
}

如果它只特定于某些控制器,那么在例如传递 ViewBag 属性会更灵活

public static class ControllerHelper
{
    public static void LoadViewBag(dynamic viewBag)
    {
         viewBag.aaa = "something";
    }
}

public class HomeController : Controller
{
    public ActionResult Index()
    {
        ControllerHelper.LoadViewBag(ViewBag);
        return View();
    }
}
于 2013-09-13T10:03:50.040 回答
4

您是否需要允许不同的控制器/视图使用一些通用属性?

然后我宁愿推荐一个通用的基本控制器,同时还将ViewBag代码包装到类型安全的属性中(让编译器控制数据一致性 - 如您所知,ViewBag它不是类型安全的,因此任何拼写错误和数据不匹配都不会被注意到,直到代码被执行)。

1. 引入具有这些包装器属性的通用控制器

public abstract class MyBaseController : Controller
{
    internal long CurrentUserId
    {
        get { return ViewBag.CurrentUserId; }
        set { ViewBag.CurrentUserId = value; }
    }

    internal Role CurrentUserRole
    {
        get { return ViewBag.CurrentUserRole; }
        set { ViewBag.CurrentUserRole = value; }
    }

    ...
}

因此,您继承的控制器可以简单地设置属性 - 或者,使用许多通用代码只需在您的基本控制器中引入一个方法 - 类似于您已经拥有的。

2. 引入具有这些包装器属性的通用视图类

public abstract class MyBaseViewPage<T> : WebViewPage<T>
{
    public string Title
    {
        get { return (string)ViewBag.Title; }
        set { ViewBag.Title = value; }
    }

    public long CurrentUserId
    {
        get { return (long)ViewBag.CurrentUserId; }
    }

    public Role CurrentUserRole
    {
        get { return ViewBag.CurrentUserRole; }
    }
}

public abstract class MyBaseViewPage : MyBaseViewPage<dynamic>
{
}

并更新web.config以让 MVC 知道您正在使用自定义基本视图:

<configuration>
  ...
  <system.web.webPages.razor>
    ...
    <pages pageBaseType="MyRootNamespace.Views.MyBaseViewPage">
      ...
    </pages>
  </system.web.webPages.razor>

现在您可以将它们用作控制器和视图中的普通属性。

于 2013-09-13T11:21:41.660 回答
4

ViewBag是您的控制器的一个属性(更具体地说是ControllerBase),并且由于静态方法不知道类实例,因此您无法访问它。

如果您想使用静态方法或什至使其成为扩展方法,则可以将控制器实例传递给该方法,但根据您的问题,此解决方案可能不是最佳的。如果您在问题中添加更多详细信息,您可能会得到更好的答案。

Public ActionResult Index()
{
    this.loadViewBag();
    return View();
}

public static void loadViewBag(this ControllerBase target)
{
    target.ViewBag.aaa = "something";
}
于 2013-09-13T10:00:37.473 回答