ASP.NET MVC 3 - 模型验证 [英] ASP.NET MVC 3 - Model Validation

查看:166
本文介绍了ASP.NET MVC 3 - 模型验证的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚学习MVC和我对设计/事情应该如何工作的几个问题。

I'm just learning MVC and I have a few questions about the design/how things are supposed to work.

我使用MVC 3剃须刀,实体框架类(例如位置),我要创建一个验证注释的哥们类。在我看来,我有一个局部视图呈现一个DevEx preSS TreeView控件(使用地点列表)和创建/编辑在树中的位置表单。我有一个LocationController,一个LocationManagementView,一个LocationManagementPartialView(包含code代表树视图)和LocationModel。该LocationModel将举行哥们类,并得到越来越孩子的方法(孩子只取一个节点展开后)。我有一个服务包装器(对于我的服务的客户端)将使用StructureMap注入。

I'm using MVC 3 and Razor, with Entity Framework classes (e.g. Location) and I'm going to create a buddy class with Validation annotations. In my View, I have a Partial View that renders a DevExpress TreeView (using a list of Locations) and a Form for creating/editing the Locations in the Tree. I have a LocationController, a LocationManagementView, a LocationManagementPartialView (contains the code for tree view), and a LocationModel. The LocationModel will hold the buddy class and get methods for getting children (the children are only fetched after a node is expanded). I have a service wrapper (for my service client) that will be injected using StructureMap.

我应该注射服务包装成控制器的构造函数或进入模型的构造?

Should I inject the service wrapper into the Controller's constructor or into the Model's constructor?

另外,我的模式已经获得使用该服务的包装从数据库(做的那些方法,模型属于这里?)获取数据的方法:例如,树视图的GetChildren

Also, my Model has get methods that use the service wrapper to fetch data from the database (do those methods belong here in the Model?): for example, GetChildren for the tree view.

此外,它正确的位置哥们类存储在型号?

Also, is it correct to store the Location buddy class in the Model?

我要确保我设计这个应用程序很好,因为它是一个更大的项目的一部分。任何设计的指针是多少AP preciated。我一直在读ScottGu的博客为MVC的东西。

I want to make sure I design this application well, as it's part of a much bigger project. Any design pointers are much appreciated. I've been reading ScottGu's blog for the MVC stuff.

参考:的http://weblogs.asp.net/scottgu/archive/2010/01/15/asp-net-mvc-2-model-validation.aspx

推荐答案

下面是几个你的框架的建议。

Here are a couple of recommendations for your "framework".

实体框架

有关每个模型返回从EF回来,提取EF模型的接口,并使用接口作为数据源,而不是实现EF类。这样做的原因是,如果你决定使用其他数据源的任何一个越跌越车型(或整个实体框架),你可以简单地确保新数据层返回相同的接口,而无需改变你的整个网络code。不足之处是确保您的接口是最新的,当你做出模型更改。

For each of your Models returned back from EF, Extract an Interface of the EF Model and use the interface as the source of data, not the implemented EF Class. The reason for this is that if you decide to use another data source for any one more or more models (or the entire Entity Framework) you can simply make sure your new Data Tier returns the same interfaces, without the need to change your entire web code. The downside is making sure your interfaces are up to date when you make model changes.

这也可以让你的视图模型来实现的EF模型的接口(与您选择的附加逻辑)。如果插入/更新的数据层所有通话接受相同的接口模式返回这是有利的。这允许您创建不同的要求,所有符合数据层需要插入/更新什么多个模型。缺点是,在你的数据层,你必须[创建一个新的EF模型] / [获取模型更新]从界面到模型映射字段。

This also allows your view models to implement the interface of an EF model (with additional logic of your choice). This is advantageous if all your calls for inserts/updates to the Data Tier accept the same interface models returned. This allows you to create multiple models with different requirements that all fit what the Data Tier needs to insert/update. The downside is that in your Data Tier you'll have to [create a new EF model]/[Get the model to update] and map the fields from the interface to the model.

视图模式

我强烈建议每个视图模型不需要被显示的实际模型(多个),而是包含该模型(多个)的类。例如:

I highly recommend that each view model is not the actual model(s) that need to be displayed, but an class that contains the model(s). Examples:

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,你可以从分离部分的意见看法。以下是如何(使用上述机型):

By passing the example "CarViewModel", you can decouple partial views from views. Here's how (using the models above):

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 接口模型,基本上从视图解耦partialview。

Now anytime you want to use the PartialViewCar you simply need to make a Model that implements the IPartialViewCar Interface, basically decoupling the partialview from the view.

验证

我会建议创建接口(类,如果你真的想要的,但实在是没有必要),有大家的验证逻辑。

I would recommend creating interfaces (classes if you really want, but there really isn't a need) that have all of you validation logic.

比方说,我们希望能够要求匿名用户键入既是品牌和模型,但注册用户只需要输入一个制作。怎么可以这样很容易做到,方法如下:(扩展更多的previous code)

Lets say we want to require anonymous users to type both a make and a model, but registered users only have to type a Make. How can this be done easily, here's how: (extending more on the previous code)

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照顾的验证。当您需要更新验证,更新一个单一的界面。这样做的缺点是它的感觉相当复杂的。

Now you can create either an AnonymouseCar or RegisteredCar, pass it into the CarViewModel, and let MVC take care of the validation. When you need to update the validation, you update a single interface. The downside to this is it feels fairly complex.

注塑和放大器;数据请求

我的preference就是尽量保持控制器操作尽可能的简单,不包括code那里检索数据。我选择不这样做的原因是,我不喜欢重复code。例如:

My preference is to try to keep the Controller Actions as simple as possible and not to include code there to retrieve data. The reason I choose not to do this is that I don't like to repeat code. For example:

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

相反,我会做这样的事情:(不是完全)

Instead I would do something like: (not completely)

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

这意味着,型材枚举的只有的时,它的要求,我没有来填充它自己。往往是错误少,如果我使用code到我的优势,而不是要求我或者其他程序员手动填充模式。

This means that profiles is Enumerated ONLY when it's requested, I don't have to populate it myself. Tends to be less bugs if I use the code to my advantage, instead of requiring me or other programmers to manually populate models.

这篇关于ASP.NET MVC 3 - 模型验证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆