如何将下拉列表数据绑定到复杂类?

时间:2010-05-08 06:53:05

标签: c# .net asp.net-mvc asp.net-mvc-2

我正在使用asp.net mvc 2.0(默认绑定模型),我遇到了这个问题。

我有一个带有下拉列表的强类型视图

<%= Html.DropDownList("List", "-----")%>

现在我有一个像

这样的模型类
Public class Test
{
    public List { get; set; } 
    public string Selected {get; set;}

    public Test()
    {
           List = new List();
           selected = "";
    }
}

现在我已经在我的控制器中了

    public ActionResult TestAction()
    {
        Test ViewModel = new Test();
        ViewModel.List = new SelectList(GetList(), "value", "text", "selected");
        return View(Test);
    }

   [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult TestAction(Test ViewModel)
    {
          return View();
    }

现在,当我第一次加载TestAction页面时,它会按预期填充下拉列表。

现在我想将所选值发布回服务器(下拉列表位于带有其他文本框的表单标记内)。所以当我看到(Test ViewModel)

时,我正试图自动绑定它

但是我得到了这个非常大的错误。

Server Error in '/' Application.
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) +98
   System.RuntimeType.CreateInstanceDefaultCtor(Boolean publicOnly, Boolean skipVisibilityChecks, Boolean skipCheckThis, Boolean fillCache) +241
   System.Activator.CreateInstance(Type type, Boolean nonPublic) +69
   System.Activator.CreateInstance(Type type) +6
   System.Web.Mvc.DefaultModelBinder.CreateModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Type modelType) +403
   System.Web.Mvc.DefaultModelBinder.BindSimpleModel(ControllerContext controllerContext, ModelBindingContext bindingContext, ValueProviderResult valueProviderResult) +544
   System.Web.Mvc.DefaultModelBinder.BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) +479
   System.Web.Mvc.DefaultModelBinder.GetPropertyValue(ControllerContext controllerContext, ModelBindingContext bindingContext, PropertyDescriptor propertyDescriptor, IModelBinder propertyBinder) +45
   System.Web.Mvc.DefaultModelBinder.BindProperty(ControllerContext controllerContext, ModelBindingContext bindingContext, PropertyDescriptor propertyDescriptor) +658
   System.Web.Mvc.DefaultModelBinder.BindProperties(ControllerContext controllerContext, ModelBindingContext bindingContext) +147
   System.Web.Mvc.DefaultModelBinder.BindComplexElementalModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Object model) +98
   System.Web.Mvc.DefaultModelBinder.BindComplexModel(ControllerContext controllerContext, ModelBindingContext bindingContext) +2504
   System.Web.Mvc.DefaultModelBinder.BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) +548
   System.Web.Mvc.ControllerActionInvoker.GetParameterValue(ControllerContext controllerContext, ParameterDescriptor parameterDescriptor) +474
   System.Web.Mvc.ControllerActionInvoker.GetParameterValues(ControllerContext controllerContext, ActionDescriptor actionDescriptor) +181
   System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName) +830
   System.Web.Mvc.Controller.ExecuteCore() +136
   System.Web.Mvc.ControllerBase.Execute(RequestContext requestContext) +111
   System.Web.Mvc.ControllerBase.System.Web.Mvc.IController.Execute(RequestContext requestContext) +39
   System.Web.Mvc.<>c__DisplayClass8.<BeginProcessRequest>b__4() +65
   System.Web.Mvc.Async.<>c__DisplayClass1.<MakeVoidDelegate>b__0() +44
   System.Web.Mvc.Async.<>c__DisplayClass8`1.<BeginSynchronous>b__7(IAsyncResult _) +42
   System.Web.Mvc.Async.WrappedAsyncResult`1.End() +141
   System.Web.Mvc.Async.AsyncResultWrapper.End(IAsyncResult asyncResult, Object tag) +54
   System.Web.Mvc.Async.AsyncResultWrapper.End(IAsyncResult asyncResult, Object tag) +40
   System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult) +52
   System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result) +38
   System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +8836913
   System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +184

那我怎么能这样做呢?

3 个答案:

答案 0 :(得分:1)

您是否考虑过使用强类型助手进行尝试?

我正在为我的观点做类似的事情,有多个下拉类别选择,我正在使用以下代码:

<%= Html.DropDownListFor(model => model.Selected, Model.List) %>

你可以试试..

你为什么在公开课测试后有括号(就我而言,这不是有效的语法)?

Public class Test() <-
{
    public List { get; set; } 
    public string Selected {get; set;}
}

答案 1 :(得分:0)

看起来反射代码期望模型对象上的无参数构造函数。您的Test班级没有。

这应该更好:

Public class Test()
{
    public Test()
    {
        this.List = new List();
        this.Selected = string.Empty;
    }

    public List { get; set; } 
    public string Selected {get; set;}
}

答案 2 :(得分:0)

谢谢Shaharyar !! (和Oded ......你的“更好的解决方案”会给出与他最初发布的相同的错误)

<%= Html.DropDownListFor(model => model.Selected, Model.List) %>

像魅力一样,现在是我弄清楚原因的时候了。