views:

270

answers:

2

Hi

I am using asp.net mvc 2.0(default binding model) and I have this problem.

I have a strongly typed view that has a dropdownlist

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

Now I have a model class like

Public class Test
{
    public List { get; set; } 
    public string Selected {get; set;}

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

Now I have in my controller this

    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();
    }

Now when I load up the TestAction page for the first time it populates the dropdown list as expected.

Now I want to post the selected value back to the server(the dropdownlist is within a form tag with some other textboxes). So I am trying to bind it automatically when it comes in as seen (Test ViewModel)

However I get this big nasty error.

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

So how can I do this?

A: 

Looks like the reflection code is expecting a parameterless constructor on your model objects. Your Test class doesn't have one.

This should work better:

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

    public List { get; set; } 
    public string Selected {get; set;}
}
Oded
There should be an automatic default one that should generated. Anyways I did try that as well and it still does not work.
chobo2
A: 

Have you considered trying it with strongly typed helpers?

I am doing similar things for my views with multiple dropdowns for category selection and I'm using following code:

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

You could try that..

And why do you have parentheses after public class Test (this isn't valid syntax as far as I'm concerned)?

Public class Test() <-
{
    public List { get; set; } 
    public string Selected {get; set;}
}
Shaharyar
Sorry I was writing this post late at night. that should not be there. It is not really the generation of the page the first time that is the problem it is the post back.
chobo2
Hmm I tried your linq way with the For and it seems to work. I don't get how though but it works!. I also find it weird how you have to do linq a bit different with having the expression separate from the source.
chobo2
With `Model.List` it gets the value of the List and applies it to the Selected property of your model via `model => model.Selected`.
Shaharyar