vaindil
vaindil

Reputation: 7844

View is passing anonymous type to controller

I'm using C# and MVC 5, but for some reason my view is passing an anonymous type back to the controller, and it's not happy about that. The specific error is:

An exception of type 'Microsoft.CSharp.RuntimeBinder.RuntimeBinderException' occurred in System.Core.dll but was not handled in user code

Additional information: 'object' does not contain a definition for 'Id'

This is the specific controller function signature:

[HttpPost, ParameterBasedOnFormName("save-continue", "continueEditing")]
public ActionResult TaskEdit(dynamic model, bool continueEditing)

The error occurs when I try to reference model.Id in that function. The beginning of the view is this:

@model ProjectModelShopModel
// ...
@using (Html.BeginForm(null, null, FormMethod.Post, Model))
{
    // code
}

How do I solve this error? I can provide more code if necessary.

EDIT: I use a dynamic type in TaskEdit because three views call that function, each with a different model. The function is nearly identical in each. I don't use inheritance because I screwed up too much early on and it would take way too much work to fix now.

Upvotes: 1

Views: 2351

Answers (2)

lazy
lazy

Reputation: 531

It is model binding problem. You are sending a post request to a single method with 3 types of models. That method has to accept that model and expose you the values of that. There are couple of ways to achieve this -

  1. Create your own model binder

    [HttpPost]
    [ModelBinder(typeof(CustomModelBinder))]
    

CustomModelBinder is an extension of default model binder. You can find the implementation here

  1. Use Form Collection instead of binding to specific model to get data

    [HttpPost]
    public ActionResult ActionName(FormCollection formData) 
    {
        var variablename = Request.Form["VariableName"]; 
    }
    

You can find the example here

Edit Modified example link for formcollection

Upvotes: 2

CodeCaster
CodeCaster

Reputation: 151586

This post confirms (without source) my guess that the default modelbinder can't really work with dynamic parameters.

The default modelbinder looks for existing properties on the parameter types (of which dynamic has very little), and then tries to map the posted fields to those properties.

Workarounds are to use public ActionResult TaskEdit(FormCollection formCollection) and fill your model in your controller, or to use a custom modelbinder.

Upvotes: 4

Related Questions