ASP.NET Core Web API模型绑定丢失MainCont的Id字段问题求助
解决ASP.NET Core Web API模型绑定丢失MainCont Id字段的问题
你遇到的问题核心很明确:当前的DeviceModelBinder里直接实例化了全新的MainCont对象,完全没有处理请求中携带的Id字段,自然会导致这个值丢失。这里提供两种实用的解决方案,你可以根据自己的场景选择:
方案一:手动在绑定器中处理Id字段
这种方法最简单直接,不需要调整绑定器的作用范围,只需要在创建MainCont实例后,从请求值提供者中取出Id并赋值:
public class DeviceModelBinder : IModelBinder { public Task BindModelAsync(ModelBindingContext bindingContext) { if (bindingContext == null) { throw new ArgumentNullException(nameof(bindingContext)); } var model1 = new MainCont(); // 新增:手动绑定Id字段 var idValue = bindingContext.ValueProvider.GetValue("Id").FirstValue; if (int.TryParse(idValue, out int id)) { model1.Id = id; } else { // 可选:如果Id是必填项,这里可以添加模型验证错误 bindingContext.ModelState.AddModelError("Id", "Id必须是有效的整数"); bindingContext.Result = ModelBindingResult.Failed(); return Task.CompletedTask; } var select = bindingContext.ValueProvider.GetValue("select").FirstValue; if (select == "SmartPhone") { var model2 = new SmartPhone(); model2.screensize = bindingContext.ValueProvider.GetValue("screensize").FirstValue; model2.imei = bindingContext.ValueProvider.GetValue("imei").FirstValue; model1.Device = model2; } else if (select == "Laptop") { var model2 = new Laptop(); model2.CPU = bindingContext.ValueProvider.GetValue("CPU").FirstValue; model2.GPu = bindingContext.ValueProvider.GetValue("GPu").FirstValue; model1.Device = model2; } bindingContext.Result = ModelBindingResult.Success(model1); return Task.CompletedTask; } }
方案二:拆分绑定职责(更推荐)
这种方法更符合单一职责原则:让默认模型绑定器处理MainCont的简单属性(比如Id),只给Device属性指定自定义绑定器,专门处理子类实例化的逻辑。
步骤1:修改自定义绑定器,只处理Device类型
public class DeviceModelBinder : IModelBinder { public Task BindModelAsync(ModelBindingContext bindingContext) { if (bindingContext == null) { throw new ArgumentNullException(nameof(bindingContext)); } var select = bindingContext.ValueProvider.GetValue("select").FirstValue; Device device = null; if (select == "SmartPhone") { var phone = new SmartPhone(); phone.screensize = bindingContext.ValueProvider.GetValue("screensize").FirstValue; phone.imei = bindingContext.ValueProvider.GetValue("imei").FirstValue; device = phone; } else if (select == "Laptop") { var laptop = new Laptop(); laptop.CPU = bindingContext.ValueProvider.GetValue("CPU").FirstValue; laptop.GPu = bindingContext.ValueProvider.GetValue("GPu").FirstValue; device = laptop; } bindingContext.Result = ModelBindingResult.Success(device); return Task.CompletedTask; } }
步骤2:在MainCont的Device属性上指定绑定器
namespace Bind.Models { public class MainCont { public int Id{ get; set; } [ModelBinder(BinderType = typeof(DeviceModelBinder))] public Device Device { get; set; } } }
注意事项
如果之前你在Controller的Action参数上给MainCont标注了[ModelBinder(BinderType = typeof(DeviceModelBinder))],现在要移除这个标注,让默认绑定器能够处理MainCont的Id字段。
这样调整后,请求中的Id会由默认绑定器自动赋值,而Device字段则由自定义绑定器实例化对应的子类,既保留了Id值,也让代码职责更清晰。
内容的提问来源于stack exchange,提问作者Jacobs Monarch
相关产品推荐
相关产品推荐

