我刚刚学习 MVC,我有一些关于设计/如何工作的问题。
我正在使用 MVC 3 和 Razor,以及 Entity Framework 类(例如位置),并且我将创建一个带有验证注释的好友类。在我的 View 中,我有一个部分 View ,它呈现一个 DevExpress TreeView(使用位置列表)和一个用于在树中创建/编辑位置的表单。我有一个 LocationController、一个 LocationManagementView、一个 LocationManagementPartialView (包含 TreeView 的代码)和一个 LocationModel。 LocationModel 将保存伙伴类并获取用于获取子级的方法(仅在展开节点后才获取子级)。我有一个服务包装器(用于我的服务客户端),将使用 StructureMap 注入(inject)。
我应该将服务包装器注入(inject)到 Controller 的构造函数中还是模型的构造函数中?
此外,我的模型具有使用服务包装器从数据库获取数据的 get 方法(这些方法属于模型中的此处吗?):例如,用于 TreeView 的 GetChildren。
此外,将 Location buddy 类存储在模型中是否正确?
我想确保我很好地设计了这个应用程序,因为它是一个更大项目的一部分。任何设计指针都非常感激。我一直在阅读 ScottGu 的博客以了解 MVC 内容。
引用号:http://weblogs.asp.net/scottgu/archive/2010/01/15/asp-net-mvc-2-model-validation.aspx
最佳答案
这里有一些针对您的“框架”的建议。
Entity Framework
对于从 EF 返回的每个模型,提取 EF 模型的接口(interface)并使用该接口(interface)作为数据源,而不是实现的 EF 类。这样做的原因是,如果您决定为任何一个或多个模型(或整个 Entity Framework )使用另一个数据源,您只需确保新数据层返回相同的接口(interface),而无需更改整个 Web代码。缺点是在进行模型更改时要确保您的界面是最新的。
这还允许您的 View 模型实现 EF 模型的接口(interface)(以及您选择的附加逻辑)。如果对数据层的插入/更新的所有调用都接受返回的相同接口(interface)模型,则这是有利的。这允许您创建具有不同要求的多个模型,这些模型都适合数据层插入/更新所需的内容。缺点是,在数据层中,您必须[创建新的 EF 模型]/[获取要更新的模型]并将字段从接口(interface)映射到模型。
查看模型
我强烈建议每个 View 模型不是需要显示的实际模型,而是包含模型的类。示例:
public class Car //Not what I recommend passing to a view
{
public string Make { get; set; }
public string Model { get; set; }
}
//Pass this to the view, i'll explain why...
public class CarViewModel : IPartialViewCar {
public Car Car { get; set; }
public ColorCollection { get; set; }
}
通过传递示例“CarViewModel”,您可以将部分 View 与 View 解耦。方法如下(使用上面的模型):
public interface IPartialViewCar
{
public Car { get; }
}
[BuildCar.cshtml]
@Model MyNameSpace.Models.Car
@Html.EditorFor(model)
[PartialViewCar.cshtml]
@Model MyNameSpace.Models.IPartialViewCar
@Html.EditorFor(model) //something like that..
现在,只要您想使用 PartialViewCar
,您只需创建一个实现 IPartialViewCar
接口(interface)的模型,基本上将 PartialView 与 View 解耦。
验证
我建议创建具有所有验证逻辑的接口(interface)(如果您确实想要的话,也可以创建类,但实际上没有必要)。
假设我们希望要求匿名用户同时输入品牌和型号,但注册用户只需输入品牌。如何轻松完成此操作,具体方法如下:(对之前的代码进行更多扩展)
public interface IAnonymouseCarValidation
{
[required]
public string Make { get; set; }
[required]
public string Model { get; set; }
}
public interface IRegisteredCarValidation
{
[required]
public string Make { get; set; }
}
public interface ICar
{
public string Make { get; set;}
public string Model { get; set; }
}
[updating the Car model to abstract and use an interface now]
public abstract class Car : ICar
{
//maybe some constructor logic for all car stuff
public string Make { get; set;}
public string Model { get; set; }
//maybe some methods for all car stuff
}
//MetadataType tells MVC to use the dataannotations on the
//typeof class/interface for validation!
[MetadataType(typeof(AnonymouseCarValidation))]
public class AnonymousCar : Car
{
}
[MetadataType(typeof(AnonymouseCarValidation))]
public class RegisteredCar : Car
{
}
[Now update the ViewModel]
public class CarViewModel : IPartialViewCar
{
public ICar Car { get; set; } //this is now ICar
public ColorCollection { get; set; }
}
现在您可以创建 AnonymouseCar
或 RegisteredCar
,将其传递到 CarViewModel,并让 MVC 负责验证。当您需要更新验证时,您可以更新单个接口(interface)。这样做的缺点是感觉相当复杂。
注入(inject)和数据请求
我的偏好是尝试使 Controller 操作尽可能简单,并且不包含用于检索数据的代码。我选择不这样做的原因是我不喜欢重复代码。例如:
public class AccountControllers
{
DataServer _Service;
public AccountControllers(DataServer Service)
{
this._Service = Service;
}
public ActionResult ShowProfiles()
{
ProfileViewModel model = new ProfileViewModel();
model.Profiles = this._Service.Profiles();
return View(model);
}
public ActionResult UpdateProfile(ProfileViewModel updatedModel)
{
service.UpdateProfile(updatedModel);
ProfileViewModel model = new ProfileViewModel();
model.Profiles = this._Service.Profiles();
return View(model);
}
}
相反,我会做类似的事情:(不完全)
public ActionResult ShowProfile(Guid ID)
{
ProfileViewModel model = new ProfileViewModel(this._service);
return View(model);
}
public ActionResult UpdateProfile(ProfileViewModel updatedModel)
{
// pass in the service, or use a property or have SetService method
updatedModel.Update(this._service)
ProfileViewModel model = new ProfileViewModel(this._service);
return View(model);
}
public class ProfileViewModel()
{
DataServer _Service;
Profile _Profile
public ProfileViewModel()
{
}
public ProfileViewModel(DataServer Service)
{
this._Service = Service;
}
public Profile Profiles()
{
get
{
if (this._service == null)
{
throw new InvalidOperationException("Service was not set.");
}
return = Service.Profiles(ID);
}
这意味着仅在请求时才枚举配置文件,我不必自己填充它。如果我利用代码来发挥我的优势,而不是要求我或其他程序员手动填充模型,那么错误往往会更少。
关于asp.net-mvc-3 - ASP.NET MVC 3 - 模型验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8157889/