编译时未知控制器,能否通过反射为ModelStateDictionary添加AddModelError?
问题解答
你的思路是可行的,不过当前代码报错是因为调用Invoke时传错了目标对象——modelProperty是PropertyInfo类型,不是ModelStateDictionary的实例,类型不匹配导致了Object does not match target type错误。
修正后的反射代码
先获取ModelState的实际实例,再调用AddModelError方法:
var modelStateProperty = controller.GetType().GetProperty("ModelState"); var modelState = modelStateProperty.GetValue(controller) as ModelStateDictionary; var addErrorMethod = typeof(ModelStateDictionary).GetMethod("AddModelError", new[] { typeof(string), typeof(string) }); addErrorMethod.Invoke(modelState, new object[] { "key", "message" });
更简洁的写法可以直接判断并调用:
if (controller.GetType().GetProperty("ModelState")?.GetValue(controller) is ModelStateDictionary modelState) { modelState.AddModelError("key", "message"); }
更高效的替代方案(无需反射)
所有ASP.NET控制器都继承自ControllerBase(Web API)或Controller(MVC),这两个基类都公开了ModelState属性。如果你的controller对象本质是这些基类的实例,直接强转就能避免反射:
if (controller is ControllerBase baseController) { baseController.ModelState.AddModelError("key", "message"); }
这种方式比反射性能更好,代码也更易读维护。
内容的提问来源于stack exchange,提问作者LenaTW
相关产品推荐
相关产品推荐

