如何从另一个控制器

问题描述:

努力学习ASP MVC从Linux的/ LAMP背景的(换句话说,我是一个福利局)引用控制器功能...如何从另一个控制器

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

下面是我的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。

我该如何参考?

广场GetMessageById(并在需要访问消息的所有其他方法)来分离并在任何需要获取Message数据的地方使用该类。

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

感谢您的帮助。您提出的MessageService类是模型还是控制器类?或者它有什么关系? – micahhoover 2011-05-21 16:12:37

+0

它是模型类/业务逻辑。 – 2011-05-21 17:22:14

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

实施例:

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

谢谢。你的抽象MessagesRepository与将此方法移动到模型类有所不同吗?你有另外一个问题(但没有问)是关于传递模型还是使用viewbag更好。 – micahhoover 2011-05-21 16:15:26

+0

@micahhoover,视图模型是一个包含视图需要的信息的类。通常它代表一个POCO类,其中包含要在视图中显示的属性。因此,通常的工作流程如下所示:控制器操作使用存储库来获取某个模型,它会根据存储库返回的信息填充视图模型,并将视图模型传递给视图。就“ViewBag”而言,我个人总是建议不要使用它。强类型视图和视图模型是构建ASP.NET MVC应用程序的正确方法。 – 2011-05-21 19:17:30

+0

感谢elarin,Darin。即使我是新手,我也很想欣赏你的建议。为什么最好有一个模型,一个视图和一个单独的模型视图?随着我获得更多的经验,我会在类型安全方面权衡你的话,但现在,我只是想找点工作。 – micahhoover 2011-05-26 07:20:30