为什么控制器首先在ASP.NET MVC中运行?

z0r*_*rch 1 c# model-view-controller asp.net-mvc asp.net-mvc-3

我想改进ASP.NET MVC框架的当前实现.当前代码:

routes.MapRoute(null, "I-want-to-fly", new { controller = "Airport", action = "Fly" });

public class AirportModel 
{
   public List<Plane> Planes { get; private set; }
   public List<Pilot> Pilots { get; private set; }

   public void AddFly(Plane plane, Pilot pilot, Passenger passenger)
   {
        // . . .
   }
}

public class AirportController
{
   private AirportModel model;

   [HttpGet]
   public ViewResult Fly(string from, string to)
   {
       var planes = return (from p in model.Planes 
                            where p.CityFrom == from && p.CityTo == to
                            select p).ToList();
       return View(planes);
   }

   [HttpPost]
   public ActionResult Fly(Plane plane, Passenger passenger, DateTime time)
   {
       if (!(ModelState.IsValid && plane.TimeOfDeparture == time))
            return View();

       var pilot = (from p in model.Pilots 
                    where p.Free && p.CanAviate(plane.Id) 
                    select p).First();
       model.AddFly(plane, pilot, passenger);

       return RedirectToAction("Succeed");
   }
}
Run Code Online (Sandbox Code Playgroud)

我的建议:

routes.MapRoute(null, "I-want-to-fly", new { model = "Airport", action = "Fly" });

public class AirportModel 
{
    private List<Plane> planes;
    private List<Pilot> pilots;

    private void AddFly(Plane plane, Pilot pilot, Passenger passenger)
    {
        // . . .
    }

    [HttpGet]
    public ViewResult Fly(string from, string to)
    {
        var planes = return (from p in model.Planes 
                             where p.CityFrom == from && p.CityTo == to
                             select p).ToList();
        return View(suitablePlanes);
    }

    [HttpPost]
    public ActionResult Fly(Plane plane, Passenger passenger, DateTime time)
    {
        if (!(ModelState.IsValid && new PlaneController().CanFly(plane, time)))
                return View();

        var pilot = (from p in pilots 
                     where p.Free && p.CanAviate(plane.Id) 
                     select p).First();
        AddFly(plane, pilot, passenger);

        return RedirectToAction("Succeed");
    }
}

public static class PlaneController
{
    public static bool CanFly(Plane plane, DateTime time)
    {
        return plane.TimeOfDeparture == time; // it will be more complex
    }
}
Run Code Online (Sandbox Code Playgroud)

你看,以这种方式我们不需要过多的控制器及其方法.Model只能通过perforce创建控制器:主要是验证用户输入(不是输入验证,业务验证).

您怎么看?这个想法可以延续吗?或者,它有什么问题?

谢谢你的回复!

更新:我注意到,由于更改模型的状态(主要是),我们需要替换控制器和视图的实现.那么,如果模型导致改变实现,为什么模型不能这样做呢?

更新2:在我看来,我解释不正确.我不希望模特做所有工作,当然不是!我试着说,不是控制器应该决定如何处理模型以及哪种视图最​​适合这个用户请求.

难道不奇怪,那个模型不知道如何自己想象,但有些控制器知道吗?

难道不奇怪,我们需要GET请求的控制器,那里没有什么可控制的吗?

我试图消除那些陌生感.

更新3:我知道它无法在任何地方应用.主要问题是:它能改进MVC当前实现的某些部分吗?大多数时候我对ASP.NET MVC感兴趣 - 我们可以

  1. 删除冗余控制器或其方法
  2. 直接与模型一起工作

用这个想法?是否有可能,这个想法有什么问题?

发现问题:

  1. 模型和视图/控制器之间的连接更强大 - 但目前我不认为这是一个问题.实际上它表明视图和控制器是在主要元素 - 模型的帮助下创建的.

更新4:我更改了代码,显示"之前/之后".也许这个例子会更好.

Maj*_*yte 8

这不是违反了MVC的整个想法吗?您的模型与控制器和视图分开.通过这种方式(您建议的方式),您将无法通过其他实现或控制器替换您的模型.

更新我:

你当然可以让你的模型也做控制器的一部分,但从那一刻起你就不再讨论MVC设计模式了.对于MVC,模型现在和不应该关于视图.这是控制器的工作.

控制器接收用户输入并通过对模型对象进行调用来启动响应.控制器接受来自用户的输入,并指示模型和视口基于该输入执行操作.

在MVC模式中,模型不仅固定在数据库模型上,它还可以是数据库模型和存储库模式的组合,您可以在其中实现业务逻辑.

我在您的提案中看到的最大问题是它使代码不可重用.我得到的模型与它的视图紧密结合,如果我想以任何我想要的方式重用模型,我真的不想要这些模型.


更新II

  • 我认为你的实际单词控制器误导你,我有一段时间的想法,你的最新评论有点证实这一点对我来说

    控制器是一些对象,用于检查用户输入与业务逻辑的对应关系.

    控制器根据用户输入进行操作,他们可能会检查用户输入,但他们检查有效性的责任会在那里停止.业务逻辑进入模型(同样,模型由MVC模式定义,而不是模型,如数据模型中).他们的主要目的是决定要显示的视图.

  • 还有一条最新评论:

    您如何看待,如果以我的方式开发[asp.net mvc],它会解决冗余控制器的问题吗?

    Asp.Net MVC遵循MVC设计模式.你的提议没有.它似乎更像是一个ModelControlled View模式,只是为了命名.此外,没有冗余控制器,控制器没有问题,它们是解决方案的组成部分.

并努力简单地阐明代码示例的含义:

namespace DataProject.Model
{
    public class AirportModel 
    {
        public List<Plane> Planes { get; set; }
        public List<Pilot> Pilots { get; set; }
        public List<Passenger> Passengers { get; set; }
        public List<Flight> Flights { get; set; }
    }

}

namespace SomeProject.Repository
{
    public class AirportRepository
    {
        private DataProject.Model.AirportModel model;

        //constructor sets the model somehow

        public bool AddFlight(Plane plane, List<Passenger> passengers, DateTime time)
        {
            //Business logic
            if (plane.TimeOfDeparture != time) return false;

            var pilot = (from p in model.Pilots 
                         where p.Free && 
                               p.CanAviate(plane.Id) 
                         select p).FirstOrDefault();
            //More Business logic
            if (pilot == null) return false;

            //Add plane, pilot and passenger to database
            model.Flights.add(new Flight{Pilot = pilot, Plane = plane, Passengers = passengers});
            //Even here you could decide to do some error handling, since you could get errors from database restrictions
            model.Save(); 

            return true;    
        }

        public List<Planes> GetPlanes(string from, string to)
        {
            return (from p in model.Planes 
                        where p.CityFrom == from && p.CityTo == to
                        select p).ToList();
        }
    }
}

namespace MVCApp.Controllers
{
    public class AirportController
    {
        private SomeProject.Repository.AirportRepository repository;

        [HttpGet]
        public ViewResult Fly(string from, string to)
        {
            var viewModel = repository.GetPlanes(from, to);
            return View(viewModel);
        }

        [HttpPost]
        public ActionResult Fly(Plane plane, List<Passenger> passengers, DateTime time)
        {
            if (!ModelState.IsValid) return View(); 

            if (!repository.AddFlight(plane, pilot, passenger)) return View();

           return RedirectToAction("Succeed");
        }
    }
}
Run Code Online (Sandbox Code Playgroud)