ASP.NET MVC5创建角色时遇“无无参构造函数”错误求助
我正在开发一个基于角色授权的ASP.NET MVC5应用,创建新角色时遭遇错误:No parameterless constructor defined for this object,尽管我以为已经定义了构造函数。
我的代码
RoleController代码
public class RoleController : Controller { private ApplicationRoleManager _roleManager; public RoleController() { } public RoleController(ApplicationRoleManager roleManager) { RoleManager = roleManager; } public ApplicationRoleManager RoleManager { get { return _roleManager ?? HttpContext.GetOwinContext().Get<ApplicationRoleManager>(); } private set { _roleManager = value; } } // GET: Role public ActionResult Index() { List<RoleViewModel> list = new List<RoleViewModel>(); foreach (var role in RoleManager.Roles) list.Add(new RoleViewModel(role)); return View(list); } public ActionResult Create() { return View(); } [HttpPost] public async Task<ActionResult> Create(RoleViewModel model) { var role = new ApplicationRole() { Name = model.Name }; await RoleManager.CreateAsync(role); return RedirectToAction("Index"); } }
RoleViewModel类代码
public class RoleViewModel { public RoleViewModel(ApplicationRole role) { Id = role.Id; Name = role.Name; } public string Id { get; set; } public string Name { get; set; } }
错误信息及堆栈跟踪
No parameterless constructor defined for this object.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.MissingMethodException: No parameterless constructor defined for this object.
Source Error:
An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.
Stack Trace:
[MissingMethodException: No parameterless constructor defined for this object.] System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean noCheck, Boolean& canBeCached, RuntimeMethodHandleInternal& ctor, Boolean& bNeedSecurityCheck) +0 System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark) +142 System.Activator.CreateInstance(Type type, Boolean nonPublic) +107 System.Activator.CreateInstance(Type type) +13 System.Web.Mvc.DefaultModelBinder.CreateModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Type modelType) +271 [MissingMethodException: No parameterless constructor defined for this object. Object type 'DivComm.Models.RoleViewModel'.] System.Web.Mvc.DefaultModelBinder.CreateModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Type modelType) +345 System.Web.Mvc.DefaultModelBinder.BindComplexModel(ControllerContext controllerContext, ModelBindingContext bindingContext) +750 System.Web.Mvc.ControllerActionInvoker.GetParameterValue(ControllerContext controllerContext, ParameterDescriptor parameterDescriptor) +446 System.Web.Mvc.ControllerActionInvoker.GetParameterValues(ControllerContext controllerContext, ActionDescriptor actionDescriptor) +137 System.Web.Mvc.Async.<>c__DisplayClass3_1.<BeginInvokeAction>b__0(AsyncCallback asyncCallback, Object asyncState) +1082 System.Web.Mvc.Async.WrappedAsyncResultBase`1.Begin(AsyncCallback callback, Object state, Int32 timeout) +163 System.Web.Mvc.Async.AsyncControllerActionInvoker.BeginInvokeAction(ControllerContext controllerContext, String actionName, AsyncCallback callback, Object state) +463 System.Web.Mvc.<>c.<BeginExecuteCore>b__152_0(AsyncCallback asyncCallback, Object asyncState, ExecuteCoreState innerState) +48 System.Web.Mvc.Async.WrappedAsyncVoid`1.CallBeginDelegate(AsyncCallback callback, Object callbackState) +73 System.Web.Mvc.Async.WrappedAsyncResultBase`1.Begin(AsyncCallback callback, Object state, Int32 timeout) +163 System.Web.Mvc.Controller.BeginExecuteCore(AsyncCallback callback, Object state) +787 System.Web.Mvc.Async.WrappedAsyncResultBase`1.Begin(AsyncCallback callback, Object state, Int32 timeout) +163 System.Web.Mvc.Controller.BeginExecute(RequestContext requestContext, AsyncCallback callback, Object state) +630 System.Web.Mvc.<>c.<BeginProcessRequest>b__20_0(AsyncCallback asyncCallback, Object asyncState, ProcessRequestState innerState) +99 System.Web.Mvc.Async.WrappedAsyncVoid`1.CallBeginDelegate(AsyncCallback callback, Object callbackState) +73 System.Web.Mvc.Async.WrappedAsyncResultBase`1.Begin(AsyncCallback callback, Object state, Int32 timeout) +163 System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContextBase httpContext, AsyncCallback callback, Object state) +544 System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +965 System.Web.HttpApplication.ExecuteStepImpl(IExecutionStep step) +172 System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)
问题原因
从堆栈跟踪可以直接定位到错误根源:RoleViewModel没有无参构造函数。ASP.NET MVC的默认模型绑定器在处理POST请求的参数时,需要通过无参构造函数创建模型实例,再将表单数据绑定到实例的属性上。你的RoleViewModel只定义了带ApplicationRole参数的构造函数,模型绑定器无法实例化这个类,因此抛出异常。
解决方案
给RoleViewModel添加一个无参构造函数,原有的带参数构造函数可以保留,用于从ApplicationRole实例转换为视图模型的场景:
public class RoleViewModel { // 新增无参构造函数,供MVC模型绑定器使用 public RoleViewModel() { } // 保留原构造函数,用于从ApplicationRole初始化视图模型 public RoleViewModel(ApplicationRole role) { Id = role.Id; Name = role.Name; } public string Id { get; set; } public string Name { get; set; } }
这样修改后,模型绑定器就能正常创建RoleViewModel实例并绑定表单数据,POST请求就能正常执行了。
内容的提问来源于stack exchange,提问作者Zahid

