模型绑定:安全类型转换返回null [英] Model Binding: Safe cast returns null

查看:67
本文介绍了模型绑定:安全类型转换返回null的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下代码段。

public async Task<ActionResult> Register(RegisterViewModel model)
{
    if (!ModelState.IsValid) return View(model as LocalRegisterViewModel);
        var user = new User
    {
        UserId = model.Username,
        Password = null,
        Email = model.Email,
        AccType = model.AccountType
    };

    var modelAsLocalRegisterViewModel = model as LocalRegisterViewModel;
    if (modelAsLocalRegisterViewModel != null)
        user.Password = modelAsLocalRegisterViewModel.Password;
    //...
}

这些类如下。 / p>

The classes looks as follows.

public class RegisterViewModel
{
    public string Username { get; set; }
    public string Email { get; set; }
    public int AccountType { get; set; }
}

public interface IInternalPassword
{
    string Password { get; set; }
    string ConfirmPassword { get; set; }
}

public class LocalRegisterViewModel : RegisterViewModel, IInternalPassword
{
    public string Password { get; set; }
    public string ConfirmPassword { get; set; }
}

LocalRegisterViewModel cshtml 页面按以下方式传递给控制器​​。

The LocalRegisterViewModel is passed to the controller as follows from a cshtml page.

@model  LocalRegisterViewModel

@{
    ViewBag.Title = "Register";
    Layout = "~/Views/Shared/_LayoutAnonymous.cshtml";
}

<h2>@ViewBag.Title.</h2>

@using (Html.BeginForm("Register", "Account", FormMethod.Post, new { @class = "form-horizontal", role = "form" }))

我的问题是, modelAsLocalRegisterViewModel 为空后

    var modelAsLocalRegisterViewModel = model as LocalRegisterViewModel;
    if (modelAsLocalRegisterViewModel != null)
        user.Password = modelAsLocalRegisterViewModel.Password;

有人可以调查一下并告诉我原因吗?

Can someone look into this and tell me why?

编辑

好像我的提问方式不好。因此,让我也阐明我的确切意图。我编写的 Register 动作旨在服务于多个ViewModel,每个ViewModel都有一些附加信息。因此,我要做的是编写一个带有公共属性的父级,并对其进行扩展以获取添加的属性。对于实例,我将 LocalRegisterViewModel 的实例传递给控制器​​,以便它将首先执行通用功能,如果传递的实例的类型为<$,则它将首先执行。 c $ c> LocalRegisterViewModel 如果将执行扩展功能。这就是为什么我需要检查传递的 RegisteredViewModel 也是 LocalRegisterViewModel 类型的原因。

Seems like my questioning style is bad. So let me clarify my exact intention as well. The Register action I have written is intended to serve multiple ViewModels, each having some additional info. So what I have done is writing a parent which carries the common attributes and extending that to get the added attributes. For an instance, I pass an instance of a LocalRegisterViewModel to the controller, so that it will first execute the common functionality and if the instance passed is of type LocalRegisterViewModel if will carry out the extended functionality. That's why I need to check the passed RegisteredViewModel is also of type LocalRegisterViewModel.

编辑2
这不是试图将基类实例分配给派生类引用。

EDIT 2 This is not trying to assign a base class instance to a derived class reference. It's a fact that following is completely valid in C#.

class Program
{
    static void Test(Parent p)
    {
        var c = p as Child;
        Console.WriteLine(c == null ? "Can't do it!" : "Can do it!");
        Console.WriteLine(c.GetType().ToString());
    }

    static void Main(string[] args)
    {
        var c = new Child();
        Test(c);
    }
}

public class Parent
{
}

public class Child : Parent
{
}


推荐答案

我认为您的困惑来自于思考您正在cshtml页面中调用控制器方法 Register(),并在那里传递模型。这不是真的。

Your confusion I think comes from thinking that you are "calling" controller method Register() from cshtml page, and "passing" your model there. It's not exactly true.

提交表单时,它将把所有输入内容发送到服务器,并发送到指定的url。这些输入可能包含 LocalRegisterViewModel 的属性,例如 Password 。请求正文可能看起来像这样:

When you submit your form, it will post all inputs to server, to the specified url. Those inputs might include properties of LocalRegisterViewModel, such as Password. Request body might look like this:

{"email": "my@email.com", "password": "bla" }

当请求到达服务器时,ASP.NET将查找与给定URL匹配的控制器动作。它看到匹配的动作是 Register(),并且该动作接受类型为 RegisterViewModel 的参数。现在,它尝试绑定该模型(通过http请求填充其属性)。绝对不知道在传入请求中是否存在其他值,例如 Password

When request comes to server, ASP.NET looks for controller action matching given url. It sees that matching action is Register() and this action accepts parameter of type RegisterViewModel. Now it tries to bind that model (fill its properties from http request). It has absolutely no idea that there are additional values, such as Password, in incoming request.

所以asp。 net将创建 RegisterViewModel 的实例并填充其属性,而忽略其余所有内容(例如密码),因为在请求本身中没有关于应该解析哪种C#类型的信息。进入。

So asp.net will create instance of RegisterViewModel and fill its properties, ignoring all the rest (such as password), because there is no information in request itself about which C# type it should be parsed into.

这篇关于模型绑定:安全类型转换返回null的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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