如何从另一个控制器引用控制器功能

时间:2011-05-21 08:41:09

标签: entity-framework asp.net-mvc-3 code-first

尝试学习来自Linux / LAMP背景的ASP MVC(换句话说,我是新手)......

出于某种原因,我似乎无法使用另一个控制器中控制器中定义的函数。

这是我的MessagesController.cs文件中的函数:

    public List<Message> GetMessagesById(string username)
    {
        return db.Messages.Where(p => p.user == username).ToList();
    }

当我尝试引用它时:

    using LemonadeTrader.Models;
    using LemonadeTrader.Controllers;     // added this to pull the Messages::getMesssagesById
    ...

    ViewBag.messages = lemondb.Messages.GetMessagesById(Membership.GetUser().ProviderUserKey.ToString());

我得到的东西是lemondb.Messages不包含名为GetMesssagesById的方法。

我如何参考?

2 个答案:

答案 0 :(得分:3)

您不应该像这样链接控制器方法,更不用说控制器不应该直接执行数据访问。我建议你将这个函数外部化到一个单独的类/存储库中,两个控制器都可以使用它。

示例:

public class MessagesRepository
{
    public List<Message> GetMessagesById(string username)
    {
        return db.Messages.Where(p => p.user == username).ToList();
    }
}

然后:

public class FooController: Controller
{
    public ActionResult Index()
    {
        var db = new MessagesRepository()
        ViewBag.messages = db.GetMessagesById(Membership.GetUser().ProviderUserKey.ToString());
        return View();
    }
}

public class BarController: Controller
{
    public ActionResult Index()
    {
        var db = new MessagesRepository()
        ViewBag.messages = db.GetMessagesById(Membership.GetUser().ProviderUserKey.ToString());
        return View();
    }
}

好的,这是第一步。通过为此存储库引入抽象,可以通过将控制器与存储库分离来改进此代码:

public interface IMessagesRepository
{
    List<Message> GetMessagesById(string username);
}

public class MessagesRepository: IMessagesRepository
{
    public List<Message> GetMessagesById(string username)
    {
        return db.Messages.Where(p => p.user == username).ToList();
    }
}

然后你可以为这些控制器使用构造函数注入:

public class FooController: Controller
{
    private readonly IMessagesRepository _repository;
    public class FooController(IMessagesRepository repository)
    {
        _repository = repository;
    }

    public ActionResult Index()
    {
        ViewBag.messages = _repository.GetMessagesById(Membership.GetUser().ProviderUserKey.ToString());
        return View();
    }
}

public class BarController: Controller
{
    private readonly IMessagesRepository _repository;
    public class BarController(IMessagesRepository repository)
    {
        _repository = repository;
    }

    public ActionResult Index()
    {
        ViewBag.messages = _repository.GetMessagesById(Membership.GetUser().ProviderUserKey.ToString());
        return View();
    }
}

最后,您将配置DI框架以将相应的实现传递到这些控制器中。

我还建议您使用强类型视图模型替换此ViewBag

public class MyViewModel
{
    public List<Message> Messages { get; set; }
}

然后:

public ActionResult Index()
{
    var model = new MyViewModel
    {
        Messages = _repository.GetMessagesById(Membership.GetUser().ProviderUserKey.ToString())
    };
    return View(model);
}

答案 1 :(得分:2)

GetMessageById(以及访问消息所需的所有其他方法)放到单独的类中,并在需要的任何位置使用该类来获取Message数据。

MessageService service = new MessageService();
ViewBag.messages = service.GetMessagesById(...);