【发布时间】:2021-02-05 11:17:32
【问题描述】:
我的模型绑定有问题。当我提交表单时,它返回我 id=0 并且设备为空?以及如何解决它。我的目标是添加新设备,并通过选择器从视图中选择设备类型。如果用户选择智能手机,则必须为智能手机添加字段。我不想将基类中的设备类型保存为 Kind 变量。在此先感谢(对不起英语)
控制器->
public IActionResult Index()
{
MainCont mainCont = new MainCont();
return View(mainCont);
}
index.cshtml ->
@model MainCont
@{
ViewData["Title"] = "Home Page";
}
<form action="home/create" method="post">
@Html.Partial("example",Model.Device)
<button type="submit">გაგზავნა</button>
</form>
example.cshtml ->
@model SmartPhone
@Html.TextBoxFor(model => model.imei)
@Html.TextBoxFor(model => model.screensize)
设备型号 ->
public abstract class Device : Object
{
}
笔记本电脑型号 ->
public class Laptop : Device
{
public string CPU { get; set; }
public string GPu { get; set; }
}
MainCont ->
public class MainCont
{
public int Id{ get; set; }
public Device Device { get; set; }
}
智能手机型号 ->
public class SmartPhone : Device
{
public string screensize { get; set; }
public string imei { get; set; }
}
模型绑定器 ->
using Bind.Models;
using Microsoft.AspNetCore.Mvc.ModelBinding;
using Microsoft.AspNetCore.Mvc.ModelBinding.Validation;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Bind
{
public class DeviceModelBinder : IModelBinder
{
private Dictionary<Type, (ModelMetadata, IModelBinder)> binders;
public DeviceModelBinder(Dictionary<Type, (ModelMetadata, IModelBinder)> binders)
{
this.binders = binders;
}
public async Task BindModelAsync(ModelBindingContext bindingContext)
{
IModelBinder modelBinder;
ModelMetadata modelMetadata;
if (bindingContext.ModelType == typeof(Laptop))
{
(modelMetadata, modelBinder) = binders[typeof(Laptop)];
}
else if (bindingContext.ModelType == typeof(SmartPhone))
{
(modelMetadata, modelBinder) = binders[typeof(SmartPhone)];
}
else
{
bindingContext.Result = ModelBindingResult.Failed();
return;
}
var newBindingContext = DefaultModelBindingContext.CreateBindingContext(
bindingContext.ActionContext,
bindingContext.ValueProvider,
modelMetadata,
bindingInfo: null,
bindingContext.ModelName);
await modelBinder.BindModelAsync(newBindingContext);
bindingContext.Result = newBindingContext.Result;
if (newBindingContext.Result.IsModelSet)
{
// Setting the ValidationState ensures properties on derived types are correctly
bindingContext.ValidationState[newBindingContext.Result] = new ValidationStateEntry
{
Metadata = modelMetadata,
};
}
}
}
}
binderprovider ->
using Bind.Models;
using Microsoft.AspNetCore.Mvc.ModelBinding;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Bind
{
public class DeviceModelBinderProvider: IModelBinderProvider
{
public IModelBinder GetBinder(ModelBinderProviderContext context)
{
if (context.Metadata.ModelType != typeof(Device))
{
return null;
}
var subclasses = new[] { typeof(Laptop), typeof(SmartPhone), };
var binders = new Dictionary<Type, (ModelMetadata, IModelBinder)>();
foreach (var type in subclasses)
{
var modelMetadata = context.MetadataProvider.GetMetadataForType(type);
binders[type] = (modelMetadata, context.CreateBinder(modelMetadata));
}
return new DeviceModelBinder(binders);
}
}
}
【问题讨论】:
标签: asp.net-mvc asp.net-core model-binding asp.net-core-3.1