C# 如何从“编辑”视图中的表单传递DTO以编辑POST操作?
我正在将CRUD用户管理添加到我的ASP.NET MVC应用程序中。我用的是身份。我使用DTO处理ApplicationUser属性,使用AutoMapper将UserDto映射到ApplicationUser,反之亦然。 当我尝试将DTO传递给Edit/POST操作时,从表单(从视图)返回,DTO的所有属性都是空的,除了Id 也就是说,在发布表单和调试应用程序时,作为参数传递给编辑操作的DTO的所有属性都为null,但Id是正确的除外 我可以将DTO传回控制器吗?我该怎么做 UserDTO.csC# 如何从“编辑”视图中的表单传递DTO以编辑POST操作?,c#,asp.net-mvc,C#,Asp.net Mvc,我正在将CRUD用户管理添加到我的ASP.NET MVC应用程序中。我用的是身份。我使用DTO处理ApplicationUser属性,使用AutoMapper将UserDto映射到ApplicationUser,反之亦然。 当我尝试将DTO传递给Edit/POST操作时,从表单(从视图)返回,DTO的所有属性都是空的,除了Id 也就是说,在发布表单和调试应用程序时,作为参数传递给编辑操作的DTO的所有属性都为null,但Id是正确的除外 我可以将DTO传回控制器吗?我该怎么做 UserDTO.c
public class UserDto
{
[Required]
public string Id { get; set; }
[Required]
[StringLength(255)]
[Display(Name = "First Name")]
public string FirstName { get; set; }
[Required]
[StringLength(255)]
public string Surname { get; set; }
[Required]
[EmailAddress]
[Display(Name = "E-mail")]
public string Email { get; set; }
[Display(Name = "E-mail Confirmed")]
public bool EmailConfirmed { get; set; }
[Display(Name = "Lockout Enddate")]
public DateTime? LockoutEndDateUtc { get; set; }
[Display(Name = "Lockout Enabled")]
public bool LockoutEnabled { get; set; }
[Display(Name = "Access Failed Count")]
public int AccessFailedCount { get; set; }
}
public class UserDetailsViewModel
{
public UserDto User { get; set; }
public UserRolesViewModel UserRolesViewModel { get; set; }
public UserDetailsViewModel(UserDto user)
{
User = user;
UserRolesViewModel = new UserRolesViewModel(user.Id);
}
}
DTO包含在传递给视图的ViewModel中。我使用相同的ViewModel查看用户的详细信息,效果良好:
UserDetailsViewModel.cs
public class UserDto
{
[Required]
public string Id { get; set; }
[Required]
[StringLength(255)]
[Display(Name = "First Name")]
public string FirstName { get; set; }
[Required]
[StringLength(255)]
public string Surname { get; set; }
[Required]
[EmailAddress]
[Display(Name = "E-mail")]
public string Email { get; set; }
[Display(Name = "E-mail Confirmed")]
public bool EmailConfirmed { get; set; }
[Display(Name = "Lockout Enddate")]
public DateTime? LockoutEndDateUtc { get; set; }
[Display(Name = "Lockout Enabled")]
public bool LockoutEnabled { get; set; }
[Display(Name = "Access Failed Count")]
public int AccessFailedCount { get; set; }
}
public class UserDetailsViewModel
{
public UserDto User { get; set; }
public UserRolesViewModel UserRolesViewModel { get; set; }
public UserDetailsViewModel(UserDto user)
{
User = user;
UserRolesViewModel = new UserRolesViewModel(user.Id);
}
}
Users/Edit.cshtml
@model MyApp.ViewModels.UserDetailsViewModel
@{
ViewBag.Title=Model.User.FirstName+“”+Model.User.姓氏;
Layout=“~/Views/Shared/_Layout.cshtml”;
}
@使用(Html.BeginForm())
{
@Html.AntiForgeryToken()
@Html.HiddenFor(model=>model.User.Id)
@Html.ValidationSummary(true,“,new{@class=“has error”})
@LabelFor(model=>model.User.FirstName,htmlAttributes:new{@class=“control label”})
@EditorFor(model=>model.User.FirstName,new{htmlAttributes=new{@class=“form control boxed”})
@Html.ValidationMessageFor(model=>model.User.FirstName,“,new{@class=“has error”})
@LabelFor(model=>model.User.lasname,htmlAttributes:new{@class=“control label”})
@Html.EditorFor(model=>model.User.namite,new{htmlAttributes=new{@class=“form control boxed”})
@Html.ValidationMessageFor(model=>model.User.namname,“,new{@class=“has error”})
@LabelFor(model=>model.User.Email,htmlAttributes:new{@class=“control label”})
@EditorFor(model=>model.User.Email,new{htmlAttributes=new{@class=“form control boxed”})
@Html.ValidationMessageFor(model=>model.User.Email,“,new{@class=“has error”})
@LabelFor(model=>model.User.emailconfirm,htmlAttributes:new{@class=“control label”})
@EditorFor(model=>model.User.emailconfirm,new{htmlAttributes=new{@class=“checkbox”})
@Html.ValidationMessageFor(model=>model.User.emailconfirm,“,new{@class=“has error”})
@LabelFor(model=>model.User.LockoutEndDateUtc,htmlAttributes:new{@class=“control label”})
@EditorFor(model=>model.User.LockoutEndDateUtc,new{htmlAttributes=new{@class=“form control boxed”})
@Html.ValidationMessageFor(model=>model.User.LockoutEndDateUtc,“,新的{@class=“has error”})
@LabelFor(model=>model.User.LockoutEnabled,htmlAttributes:new{@class=“control label”})
@EditorFor(model=>model.User.LockoutEnabled)
@Html.ValidationMessageFor(model=>model.User.LockoutEnabled,“,新的{@class=“has error”})
@LabelFor(model=>model.User.AccessFailedCount,htmlAttributes:new{@class=“control label”})
@EditorFor(model=>model.User.AccessFailedCount,new{htmlAttributes=new{@class=“form control boxed”})
@Html.ValidationMessageFor(model=>model.User.AccessFailedCount,”,新的{@class=“has error”})
}
@ActionLink(“返回列表”、“索引”)
@Html.Partial(“_UserRoles”,Model.UserRolesViewModel)
@节脚本
{
@Scripts.Render(“~/bundles/Scripts用户角色”)
}
根据视图,您的模型是MyApp.ViewModels.UserDetailsViewModel
,因此当您提交表单时,它会将UserDetailsViewModel模型发送到操作。但编辑操作需要UserDTO模型,因此绑定将由于模型不匹配而无法工作。您应该将UserDetailsViewModel作为编辑操作的输入参数,并从中读取UserDto,如下所示(更改了编辑操作的两行)
ASP.NET无法正确反序列化
UserDto
,因为HTTP请求变量与UserDto类中的属性不匹配。这种情况最有可能发生,因为请求值被标记为,例如,User.FirstName
,而当您的cshtml页面转换为HTML时,仅标记为FirstName
。问题的核心是,您将UserDetailViewModel
关联为视图的模型,同时希望将更平坦的UserDto的实例反序列化为类
发出的HTML
让我们仔细看看。首先,这里是表单中的一个片段
<div class="form-group">
@Html.LabelFor(model => model.User.Email, htmlAttributes: new { @class = "control-label" })
@Html.EditorFor(model => model.User.Email, new { htmlAttributes = new { @class = "form-control boxed" } })
@Html.ValidationMessageFor(model => model.User.Email, "", new { @class = "has-error"})
</div>
另外,请注意上面语法中的Name
属性区分大小写。不知道这是否有帮助,但它显示了在mvc中工作的dto:如果在控制器中的编辑方法中将参数更改为UserDetailsViewModel类型,那么模型绑定工作吗?谢谢,这就是它的要点,我现在明白了,该操作需要与传递给视图的模型相同的模型。我不能告诉你
@Html.EditorFor(model => model.User.Email, new { htmlAttributes = new { Name = "email", @class = "form-control boxed" } })