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感兴趣 - 我们可以
用这个想法?是否有可能,这个想法有什么问题?
发现问题:
更新4:我更改了代码,显示"之前/之后".也许这个例子会更好.
这不是违反了MVC的整个想法吗?您的模型与控制器和视图分开.通过这种方式(您建议的方式),您将无法通过其他实现或控制器替换您的模型.
你当然可以让你的模型也做控制器的一部分,但从那一刻起你就不再讨论MVC设计模式了.对于MVC,模型现在和不应该关于视图.这是控制器的工作.
控制器接收用户输入并通过对模型对象进行调用来启动响应.控制器接受来自用户的输入,并指示模型和视口基于该输入执行操作.
在MVC模式中,模型不仅固定在数据库模型上,它还可以是数据库模型和存储库模式的组合,您可以在其中实现业务逻辑.
我在您的提案中看到的最大问题是它使代码不可重用.我得到的模型与它的视图紧密结合,如果我想以任何我想要的方式重用模型,我真的不想要这些模型.
我认为你的实际单词控制器误导你,我有一段时间的想法,你的最新评论有点证实这一点对我来说
控制器是一些对象,用于检查用户输入与业务逻辑的对应关系.
控制器根据用户输入进行操作,他们可能会检查用户输入,但他们检查有效性的责任会在那里停止.业务逻辑进入模型(同样,模型由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)