[英]ASP.NET Core MVC - Data binding from form data to view model
我正在开发一个基于 .NET 6 框架的 ASP.NET Core MVC 应用程序。 我想从我的表单中检索一个与我的视图模型的类成员的属性相匹配的值。
我所有特定数据库实体的抽象模型:
public abstract class MyAbstractDatabaseEntity
{
[Column(TypeName = "bit"), Required, MaxLength(1), Unicode(false)]
public bool SafeDelete { get; set; } = false;
[Column(TypeName = "datetime")]
public DateTime CreationDate { get; set; }
[Required, MaxLength(12), Unicode(false)]
public string CreationUserID { get; set; }
[Column(TypeName = "datetime")]
public DateTime UpdateDate { get; set; }
[Required, MaxLength(12), Unicode(false)]
public string UpdateUserID { get; set; }
}
我的特定数据库实体之一:
[Table("MyDatabaseTable")]
public class MyEntity : MyAbstractDatabaseEntity
{
[Key]
[Required]
public int ID { get; set; }
[Display(Name = "Account number"), Required, Unicode(false)]
[RegularExpression(@"^(\d+)$")]
[MaxLength(11)]
public string AccountNumber { get; set; }
[Column(TypeName = "bit")]
[MaxLength(1)]
[Required]
public bool IsDraft { get; set; } = false;
}
我的视图模型
public class MyViewModel
{
public MyEntity Entity { get; set; } = new();
public string Title { get; set; }
}
我的控制器
public class MyHomeController : Controller
{
// GET: MyHome/Index
public IActionResult Index()
{
MyViewModel model = new()
{
Title = "My page - Search account details"
};
return View(model);
}
// POST: MyHome/FindAccountDetails
[HttpPost, ValidateAntiForgeryToken]
public ActionResult FindBankAccountDetails(MyViewModel model)
{
if (!ModelState.IsValid)
{
return View(model);
}
return PartialView("_Details", model);
}
}
我的观点 :
@using MyApplication
@model MyViewModel
<div class="container">
<div class="container-header">
<h2>@Model.Title</h2>
</div>
<div class="container-body">
@using (Html.AjaxBeginForm("FindBankAccountDetails", "MyHome", new AjaxOptions
{
HttpMethod = "POST",
UpdateTargetId = "request-general-information",
InsertionMode = InsertionMode.Replace
}))
{
<div class="form-group">
<label asp-for="Entity.AccountNumber" class="control-label">Account number</label>
<input asp-for="Entity.AccountNumber" class="form-control" />
<span asp-validation-for="Entity.AccountNumber" class="text-danger"></span>
</div>
<button type="submit" class="btn btn-primary">Search details</button>
}
</div>
</div>
<div class="piw-filter" id="request-general-information"></div>
@section Scripts {
@{
await Html.RenderPartialAsync("_ValidationScriptsPartial");
}
}
我的问题:在验证时,程序无法识别视图模型。 该程序在控制台中返回以下消息:
Microsoft.AspNetCore.Hosting.Diagnostics: Information: Request starting HTTP/1.1 POST https://localhost:44323/MyHome/FindBankAccountDetails application/x-www-form-urlencoded;+charset=UTF-8 283
Microsoft.AspNetCore.Routing.EndpointMiddleware: Information: Executing endpoint 'MyApplication.MyHomeController.FindBankAccountDetails (‘MyApplication)'
Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker: Information: Route matched with {action = "FindBankAccountDetails", controller = "MyHome"}. Executing controller action with signature Microsoft.AspNetCore.Mvc.ActionResult FindBankAccountDetails(MyApplication.MyViewModel) on controller MyApplication.MyHomeController (‘MyApplication).
Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker: Information: Executed action MyApplication.MyHomeController.FindBankAccountDetails (‘MyApplication) in 3.8675ms
Microsoft.AspNetCore.Routing.EndpointMiddleware: Information: Executed endpoint 'MyApplication.MyHomeController.FindBankAccountDetails (‘MyApplication)'
Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware: Error: An unhandled exception has occurred while executing the request.
System.InvalidCastException: The field of type System.Boolean must be a string, array or ICollection type.
at System.ComponentModel.DataAnnotations.MaxLengthAttribute.IsValid(Object value)
at System.ComponentModel.DataAnnotations.ValidationAttribute.IsValid(Object value, ValidationContext validationContext)
at System.ComponentModel.DataAnnotations.ValidationAttribute.GetValidationResult(Object value, ValidationContext validationContext)
at Microsoft.AspNetCore.Mvc.DataAnnotations.DataAnnotationsModelValidator.Validate(ModelValidationContext validationContext)
at Microsoft.AspNetCore.Mvc.ModelBinding.Validation.ValidationVisitor.ValidateNode()
at Microsoft.AspNetCore.Mvc.ModelBinding.Validation.ValidationVisitor.VisitSimpleType()
at Microsoft.AspNetCore.Mvc.ModelBinding.Validation.ValidationVisitor.VisitImplementation(ModelMetadata& metadata, String& key, Object model)
at Microsoft.AspNetCore.Mvc.ModelBinding.Validation.ValidationVisitor.Visit(ModelMetadata metadata, String key, Object model)
at Microsoft.AspNetCore.Mvc.ModelBinding.Validation.ValidationVisitor.VisitChildren(IValidationStrategy strategy)
at Microsoft.AspNetCore.Mvc.ModelBinding.Validation.ValidationVisitor.VisitComplexType(IValidationStrategy defaultStrategy)
at Microsoft.AspNetCore.Mvc.ModelBinding.Validation.ValidationVisitor.VisitImplementation(ModelMetadata& metadata, String& key, Object model)
at Microsoft.AspNetCore.Mvc.ModelBinding.Validation.ValidationVisitor.Visit(ModelMetadata metadata, String key, Object model)
at Microsoft.AspNetCore.Mvc.ModelBinding.Validation.ValidationVisitor.VisitChildren(IValidationStrategy strategy)
at Microsoft.AspNetCore.Mvc.ModelBinding.Validation.ValidationVisitor.VisitComplexType(IValidationStrategy defaultStrategy)
at Microsoft.AspNetCore.Mvc.ModelBinding.Validation.ValidationVisitor.VisitImplementation(ModelMetadata& metadata, String& key, Object model)
at Microsoft.AspNetCore.Mvc.ModelBinding.Validation.ValidationVisitor.Visit(ModelMetadata metadata, String key, Object model)
at Microsoft.AspNetCore.Mvc.ModelBinding.Validation.ValidationVisitor.Validate(ModelMetadata metadata, String key, Object model, Boolean alwaysValidateAtTopLevel, Object container)
at Microsoft.AspNetCore.Mvc.ModelBinding.ObjectModelValidator.Validate(ActionContext actionContext, ValidationStateDictionary validationState, String prefix, Object model, ModelMetadata metadata, Object container)
at Microsoft.AspNetCore.Mvc.ModelBinding.ParameterBinder.EnforceBindRequiredAndValidate(ObjectModelValidator baseObjectValidator, ActionContext actionContext, ParameterDescriptor parameter, ModelMetadata metadata, ModelBindingContext modelBindingContext, ModelBindingResult modelBindingResult, Object container)
at Microsoft.AspNetCore.Mvc.ModelBinding.ParameterBinder.BindModelAsync(ActionContext actionContext, IModelBinder modelBinder, IValueProvider valueProvider, ParameterDescriptor parameter, ModelMetadata metadata, Object value, Object container)
at Microsoft.AspNetCore.Mvc.Controllers.ControllerBinderDelegateProvider.<>c__DisplayClass0_0.<<CreateBinderDelegate>g__Bind|0>d.MoveNext()
--- End of stack trace from previous location ---
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeInnerFilterAsync>g__Awaited|13_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResourceFilter>g__Awaited|25_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResourceExecutedContextSealed context)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeFilterPipelineAsync()
--- End of stack trace from previous location ---
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Logged|17_1(ResourceInvoker invoker)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Logged|17_1(ResourceInvoker invoker)
at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
at Microsoft.AspNetCore.Session.SessionMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Session.SessionMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Session.SessionMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Session.SessionMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Diagnostics.StatusCodePagesMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Diagnostics.StatusCodePagesMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware.<Invoke>g__Awaited|6_0(ExceptionHandlerMiddleware middleware, HttpContext context, Task task)
Microsoft.AspNetCore.Routing.EndpointMiddleware: Information: Executing endpoint '405 HTTP Method Not Supported'
Microsoft.AspNetCore.Routing.EndpointMiddleware: Information: Executed endpoint '405 HTTP Method Not Supported'
Microsoft.AspNetCore.Hosting.Diagnostics: Information: Request finished HTTP/1.1 POST https://localhost:44323/MyHome/FindBankAccountDetails application/x-www-form-urlencoded;+charset=UTF-8 283 - 405 - text/plain 34.4795ms
浏览器然后显示此消息: https://localhost:44323/MyHome/FindBankAccountDetails 405 (Method Not Allowed)
我无法使用断点到达FindBankAccountDetails
控制器方法。
为什么没有从FindBankAccountDetails
控制器方法中检索MyViewModel
视图模型?
谢谢你的帮助。
根据文档属性 [MaxLength()] 指定数组或字符串的最大长度。 IsDraft 是布尔值,这就是您得到 InvalidCastException 的原因。
[Column(TypeName = "bit")]
[MaxLength(1)]
[Required]
public bool IsDraft { get; set; } = false;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.