开发者

Why controllers run first in the ASP.NET MVC?

I want to improve current implementation of the ASP.NET MVC Framework. Current code:

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

My proposal:

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

You see, in such way we don't need excessive count of controllers and their methods. Model would create controller only by perforce: mostly to verify user input (not input validation, business validation).

What do you think, can this idea have a continuation? Or, what is wrong with it?

Thanks for your replies!

UPDATE: I noticed, that we need to replace implementa开发者_开发百科tions of controller and view as a result of changing the model's state (mostly). So, if model causes to change the implementation, why model cannot do it?

UPDATE 2: It seems to me I explained incorrectly. I don't want model to do all work, of course no! I try to say, that not controller should decide what to do with model and what view is the most suitable for this user request.

Doesn't it strange, that model doesn't know how to visualize itself, but some controller knows?

Doesn't it strange, than we need controller for the GET request, where there is nothing to control?

I try to remove those strangenesses.

UPDATE 3: I understand that it cannot be applied anywhere. The main question is: can it improve some part of current implementations of MVC ? Mostly I'm interested in ASP.NET MVC -- can we

  1. remove redundant controllers or some its methods
  2. work directly with models

using this idea? Is it possible and what are the problems of this idea?

Found problems:

  1. More strong connection between model and view/controller -- but currently I don't think it's a problem. Actually it shows that views and controllers were created in help for the major element -- model.

UPDATE 4: I changed the code, showing "before/after". Maybe this example will be better.


Doesn't this just violate the whole idea of MVC? Your model is separated from your controller and your view. In this way (the way you propose) you would not be able to replace your model by another implementation, or your controller for that matter.

updated I:

You could of course let your model do the part of the controller as well, but from that moment on you're not talking about the MVC design pattern anymore. For MVC, the model does and should not now about the view. That's the controllers job.

The controller receives user input and initiates a response by making calls on model objects. A controller accepts input from the user and instructs the model and viewport to perform actions based on that input.

In the MVC pattern, the Model isn't just fixed to your database model, it could be a combination of your database model and a repository pattern as well, where you implement your business logic.

The biggest problem I see with your proposal is that it makes code non-reusable. I get a model that is tightly coupled with it's views which I really don't want if I want to reuse the model in whatever way I might want to.


Update II

  • I think your are being mislead by the actual word Controller, I had that thought for a while and your latest comment sort of confirms this for me

    Controllers are some objects, that check correspondence of user input to business-logic.

    Controllers act upon user input, they might check the user input but their responsibility for checking validity stops there. Business logic goes in the Model (again, the Model as defined by the MVC pattern, not the model as in datamodel). Their main purpose is deciding what View to display.

  • Also from one of your latest comments:

    How do you think, if [asp.net mvc] would be developed in my way, would it solve problem of redundant controllers?

    Asp.Net MVC follows the MVC design pattern. Your proposal does not. It seem more like a ModelControlled View pattern, just to coin a name. Also, there are no redundant controllers, the controllers are no problem, they are an integral part of the solution.

And an effort to simplistically clarify what I mean with a code example:

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


No offense intended but how exactly is this an improvement?

So you've made a class called a PersonModel that isn't really doing "model things" at all - it is doing the work that Controllers do - you've got it handling gets and posts and calling out for the display of Views and then you've got a static "Controller" that really controlling nothing and is concerning itself with business logic. Honestly, I don't get how this is an improvement.

A concrete example of is you've got a controller checking whether Age >= 18, which is a very "business rules" thing for a controller to be doing. That's not the purpose of a controller. That's the job of a model object - to concern itself with things like business logic. Controllers, as one person put it, are more of an electronic curator. In your example, you've relegated it to something far less than a curator.

There are distinct roles that objects play in an MVC application. Views show us stuff and provide us with ways to interact with the application. Controllers handle the input coming from the View and serve up views that are needed. Models provides a place to put data and the logic and business rules that the model encompasses. Services handle things like persisting data to some store, like a DB.


You can do everything in one class without controllers at all but you want "separte of concerns" So the controller is responsible for the http request and validation and the model is responsible only for the data.


You are the programmer then you could agree or disagree with MVC pattern. But the pattern which you described doesn't support the separation of concern and it breaks out the whole idea about MVC

This has nothing to do with MVC.

This is 'MVNothing'

:) Just kidding *_^

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜