C# 模型绑定:安全强制转换返回null
我有以下片段C# 模型绑定:安全强制转换返回null,c#,types,casting,C#,Types,Casting,我有以下片段 public async Task<ActionResult> Register(RegisterViewModel model) { if (!ModelState.IsValid) return View(model as LocalRegisterViewModel); var user = new User { UserId = model.Username, Password = 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;
//...
}
LocalRegisterViewModel
从cshtml
页面传递给控制器,如下所示
@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" }))
有人能调查一下并告诉我原因吗
编辑
看来我的提问方式不好。因此,让我澄清一下我的确切意图。我编写的Register
操作旨在为多个ViewModels提供服务,每个ViewModels都有一些附加信息。因此,我所做的是编写一个带有公共属性的父级,并扩展它以获得添加的属性。对于一个实例,我将LocalRegisterViewModel
的一个实例传递给控制器,以便它首先执行公共功能,如果传递的实例类型为LocalRegisterViewModel
if,它将执行扩展功能。这就是为什么我需要检查传递的RegisteredViewModel
也是类型LocalRegisterViewModel
编辑2
这不是试图将基类实例分配给派生类引用。事实上,以下内容在C#中完全有效
对,;因此,如果:
var modelAsLocalRegisterViewModel = model as LocalRegisterViewModel;
给出null
,则正好有两个选项:
为model
null
是某种东西,但不是model
LocalRegisterViewModel
模型
,并找出它是什么。我们不能告诉您:它不在显示的代码中。但是string typeName=model?.GetType()?.Name代码>应该告诉你哪个;它将返回null
或model
所属类型的名称
通过最近的编辑,我们可以看到model
是一个RegisterViewModel
;但是:听起来它不是一个LocalRegisterViewModel
。因为有一个继承树,所以听起来像是model
是基本类型(RegisterViewModel
)或者是与LocalRegisterViewModel
无关的不同的子类型;因此,如果:
var modelAsLocalRegisterViewModel = model as LocalRegisterViewModel;
给出null
,则正好有两个选项:
model
为null
model
是某种东西,但不是LocalRegisterViewModel
因此:您需要查看模型
,并找出它是什么。我们不能告诉您:它不在显示的代码中。但是string typeName=model?.GetType()?.Name代码>应该告诉你哪个;它将返回null
或model
所属类型的名称
通过最近的编辑,我们可以看到model
是一个RegisterViewModel
;但是:听起来它不是一个LocalRegisterViewModel
。因为有一个继承树,听起来像是模型
要么是基类型(RegisterViewModel
)要么是与LocalRegisterViewModel
无关的不同的子类型,我想你的困惑来自于从cshtml页面“调用”控制器方法Register()
,并“传递”你的模型。这不完全是真的
当您提交表单时,它会将所有输入发送到服务器,发送到指定的url。这些输入可能包括LocalRegisterViewModel
的属性,例如Password
。请求主体可能如下所示:
{"email": "my@email.com", "password": "bla" }
当请求到达服务器时,ASP.NET将查找与给定url匹配的控制器操作。它看到匹配的操作是Register()
,该操作接受类型为RegisterViewModel
的参数。现在它尝试绑定该模型(从http请求填充其属性)。它完全不知道传入请求中是否有其他值,例如密码
因此asp.net将创建RegisterViewModel的实例并填充其属性,忽略所有其他属性(如密码),因为请求本身没有关于应该解析为哪种C类型的信息。我认为您的困惑来自于“调用”控制器方法Register()
从cshtml页面,并在那里“传递”您的模型。这不完全是真的
当您提交表单时,它会将所有输入发送到服务器,发送到指定的url。这些输入可能包括LocalRegisterViewModel
的属性,例如Password
。请求主体可能如下所示:
{"email": "my@email.com", "password": "bla" }
当请求到达服务器时,ASP.NET将查找与给定url匹配的控制器操作。它看到匹配的操作是Register()
,该操作接受类型为RegisterViewModel
的参数。现在它尝试绑定该模型(从http请求填充其属性)。它完全不知道传入请求中是否有其他值,例如密码
因此,asp.net将创建RegisterViewModel的实例并填充其属性,忽略所有其他属性(如密码),因为请求本身没有关于应将其解析为哪个C类型的信息。如果您不希望强制转换失败,那么不要将用作操作符,使用(LocalRegisterViewModel)型号
。它将抛出一个异常,说明什么不能被转换成什么。请原谅我的不完整问题。我刚刚注意到丢失的部分。我已经更新了它。我认为模型
永远不能注册为模型
。它是asp.net mvc控制器操作的参数,并从http请求绑定。因此,它将始终是类型RegisteredViewModel
,而不是任何其他(子)类型。我认为,您的困惑来自于您以某种方式“调用”控制器方法,将您的模型传递到那里。这不完全是真的。当您提交表单时,它会将所有值发布到服务器。这些值可能包括的所有属性
{"email": "my@email.com", "password": "bla" }