派生类的控制器动作 [英] Controller Action with Derived Classes

查看:89
本文介绍了派生类的控制器动作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个基类和两个派生类:

I have one base class and two derived classes:

public class UserModel {
    public int Id {get; set; }
    public string Name {get; set; }
    public UserType UserType {get; set;}
}

public class StudentModel : UserModel {
    public string StudentProperty {get; set;}
}

public class TeacherModel : UserModel {
    public string TeacherProperty {get; set;}
}

在我的控制器ProfileController.cs中,我执行以下两个操作:

In my controller ProfileController.cs I have the following two actions:

public virtual ActionResult Detail(int id)
{
    var userModel = _userService.Get(id);

    return view(usermodel);
}

public virtual ActionResult Save(UserModel userModel)
{
    _userService.Save(userModel);
}

我有一个视图可以显示学生和老师的个人资料.我的问题如下:

I have one view to show the profile of both Students and Teacher. My problem is the following:

在保存时,通过使用动作Save(UserModel userMode),StudentModel和TeacherModel的其他属性(分别为StudentProperty和TeacherProperty)显然未绑定到UserModel.所以我的问题是:

when saving, using the action Save(UserModel userMode), the additional properties of StudentModel and TeacherModel (StudentProperty and TeacherProperty respectively) are obviously not bound to UserModel. So my questio is:

设置Controller Action以便我可以传递派生类(StudentModel或TeacherModel)的正确方法是什么?

仅供参考,我已经尝试过自定义资料夹(请参见下文),但是,我不知道这是否是处理此问题的好方法.

FYI, I have tried a custom binder (see below), however, I don't know if this is a good way to handle this.

public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
    var form = controllerContext.HttpContext.Request.Form;

    switch (form["UserType"])
    {
        case "student":
            {
                var studentModel = bindingContext.Model as StudentModel;                        
                return studentModel;
            }
        case "Teacher":
            {
                var teacherModel = bindingContext.Model as TeacherModel;
                medico.TeacherProperty = form["TeacherProperty"];
                return teacherModel;
            }
    }

    return bindingContext.Model;
}

推荐答案

多态模型绑定的最大问题是安全性之一.毕竟,您实际上是在允许客户端控制如何解释数据.您必须注意,例如,用户不能修改帖子,并告诉服务器您的UserModel实际上是AdministratorModel,而您现在是管理员.

The biggest problem with polymorphic model binding is one of security. After all, you are effectively allowing the client to control how the data gets interpreted. You have to be careful that, for example, a user can't modify the post and tell the server that your UserModel is actually an AdministratorModel and that you are now an administrator.

在您的用例中,我不知道您的应用程序是做什么的..但是假设它是某种记录保存应用程序,请想象一个学生可以通过更改提交给服务器的类型来使自己成为一名老师,现在他们可以更改自己的成绩或其他学生的成绩.

In your use case, I don't know what your app does.. but assuming it's some kind of record keeping application, imagine that a student can make themselves a teacher just by altering the type submitted to the server, and now they can change their own grades, or those of other students.

但是,如果这不是真正的问题,那么一个相当简单的机制就是简单地做到这一点:

If, however, this is not really an issue, then a fairly simple mechanism is to simply do this:

public virtual ActionResult Save(UserModel userModel)
{
    TeacherModel tmodel = null;
    StudentModel smodel = null;
    if (userModel.UserType == UserType.Teacher) {
        tmodel = new TeacherModel();
        UpdateModel<TeacherModel>(tmodel);
    }
    else {
        smodel = new StudentModel();
        UpdateModel<StudentModel>(smodel);
    }

    _userService.Save((UserModel)tmodel ?? smodel);
}

您在问题中提出的自定义模型绑定器方法也很好,如果将其用于多种方法,则是一个更好的选择,但对于维护应用程序的人来说不是那么明显.

The custom model binder approach you proposed in your question is also fine, and a better choice if this is used in multiple methods, but is not quite so obvious to someone maintaining the application.

实际上,在这种情况下,假设您的模型类型基于某种安全机制,更好的解决方案是根据用户的角色实例化正确的模型.因此,当您的请求进入时,您将检查用户权限,如果他们是教师角色,则实例化TeacherModel对象,如果他们是学生,则实例化StudentModel对象,这样最终用户就没有任何东西可以改变它的工作方式.

In fact, a better solution in a case like this, assuming that your model type is based on some kind of security mechanism, is to instantiate the correct model based on the role of the user. So, when your request comes in, you check the users permissions, and if they are in the Teacher role, you instantiate a TeacherModel object and if they're a student you instantiate a StudentModel object, and that way there is nothing the end user can do to change how that works.

即,类似这样的东西:

public virtual ActionResult Save(UserModel userModel)
{
    TeacherModel tmodel = null;
    StudentModel smodel = null;
    // lookup user in database and verify the type of user they are
    var user = UserManager.GetUser(userModel.UserId)
    if (user.Role == "Teacher")
        tmodel = new TeacherModel();
        UpdateModel<TeacherModel>(tmodel);
    }
    else {
        smodel = new StudentModel();
        UpdateModel<StudentModel>(smodel);
    }

    _userService.Save((UserModel)tmodel ?? smodel);
}

这篇关于派生类的控制器动作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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