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

发布于 2024-11-09 08:44:11 字数 676 浏览 0 评论 0原文

试图学习来自 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());

我得到了类似于柠檬数据库的内容。Messages 不包含名为 GetMesssagesById 的方法。

我该如何引用它?

Trying to learn ASP MVC coming from Linux/LAMP background (in other words I'm a newb) ...

For some reason I can't seem to use a function defined in a controller in another controller.

Here's the function in my MessagesController.cs file:

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

When I try to reference it:

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

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

I get something along the lines of lemondb.Messages does not contain a method called GetMesssagesById.

How do I reference it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

歌枕肩 2024-11-16 08:44:11

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

示例:

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);
}

You shouldn't be linking controller methods like this, not to mention that controllers shouldn't be performing data access directly. I would recommend you externalizing this function into a separate class/repository which could be used by both controllers.

Example:

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

and then:

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();
    }
}

OK, that's the first step. This code could be improved by decoupling the controllers from the repository by introducing an abstraction for this repository:

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();
    }
}

then you could use constructor injection for those controllers:

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();
    }
}

finally you would configure your DI framework to pass the corresponding implementation into those controllers.

I would also recommend you replacing this ViewBag with a strongly typed view model:

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

and then:

public ActionResult Index()
{
    var model = new MyViewModel
    {
        Messages = _repository.GetMessagesById(Membership.GetUser().ProviderUserKey.ToString())
    };
    return View(model);
}
別甾虛僞 2024-11-16 08:44:11

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

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

Place GetMessageById (and all other methods needed for accessing messages) to separate class and use the class everywhere you need to get Message data.

MessageService service = new MessageService();
ViewBag.messages = service.GetMessagesById(...);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文