ViewBag在控制器的静态方法中

时间:2013-09-13 09:55:15

标签: asp.net-mvc asp.net-mvc-3 asp.net-mvc-4

我是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'需要对象引用。

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

谢谢。

3 个答案:

答案 0 :(得分:9)

只需将它作为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();
    }
}

答案 1 :(得分:4)

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

如果您想使用静态方法甚至将其作为扩展方法,可以将控制器实例传递给方法,但根据您的问题,此解决方案可能是次优的。如果您在问题中添加更多详细信息,则可以获得更好的答案。

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

public static void loadViewBag(this ControllerBase target)
{
    target.ViewBag.aaa = "something";
}

答案 2 :(得分: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>

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