MVC3 and Razor - How to place a dynamic value for hidden field?

13,082

Solution 1

To avoid the Extension methods cannot be dynamically dispatched exception, use a model instead of ViewBag so you will not be using dynamic objects (this will avoid all the unnecessary casting in the View and is more in line with MVC style in general):

In your action when you return the view:

return View("ViewName", db.EAList.ToList());

In your view, the first line should be:

@model IEnumerable<EAListItem> //or whatever the type name is

Then just do:

@foreach(var item in Model)

Solution 2

I had the same problem, found that a simple cast solved my problem.

@Html.Hidden("id", (string) ViewBag.ebook.isbn)

Solution 3

In Razor, once you are in "C# land", you no longer need to prefix values with @ sign.

This should suffice:

@Html.Hidden("EstadoDeAlmaID", item.EAID)

Check out Scott Gu's article covering the syntax for more help.

Update

And I would also move your <li></li> within your using block, as Razor works better when you wrap HTML blocks inside of a code blocks.

Also, your Html.BeginForm should live outside of your loop.

@using (@Html.BeginForm("Duplicate, "Daily"))
{
    <ul>
        @foreach (? item in ViewBag.EAList)
        {
            <li>
                <p>@item.AuthorComment</p>
                @Html.Hidden("EstadoDeAlmaID", item.EAID)
                @Html.Hidden("PosterID", Session["id"].ToString())
                <input type="submit" value="Send" />
            </li>
        }
    </ul>
}

Where ? in the foreach loop is the type of your items in EAList.

Solution 4

You got the error, "Extension methods cannot be dynamically dispatched"... therein lies your trouble.

You should declare you loop variable not to be of type dynamic, but of the actual type in the collection. Then remove the @ from the item.EAID call inside the @Html.Hidden() call.

Share:
13,082
Rubia Gardini
Author by

Rubia Gardini

Updated on July 23, 2022

Comments

  • Rubia Gardini
    Rubia Gardini almost 2 years

    I'm a beginner about Razor, and sometimes I get stuck with really simple things.

    I have this foreach loop:

    @foreach (dynamic item in ViewBag.EAList)
    {
    <li>
        @using (@Html.BeginForm("Duplicate, "Daily"))
        {
            <p>@item.AuthorComment</p>
            @Html.Hidden("EstadoDeAlmaID", @item.EAID)
            @Html.Hidden("PosterID", Session["id"].ToString())
            <input type="submit" value="Send" />
        }
    </li>
    }
    

    This line:

    @Html.Hidden("EstadoDeAlmaID", @item.EAID)
    

    Doesn't work, and I don't know how to make it work, I tried many ways, without @, with (--), with @(--)...

    Could someone help me to display the dynamic value in my hidden field? In addition, if someone know about a good Razor samples websites, I would be very thankful.

  • Andrew Barber
    Andrew Barber over 12 years
    I don't think it's a good idea to put a form tag outside of li tags. It's invalid html. Only li tags are legal as direct descendants of ul or ol.
  • Rubia Gardini
    Rubia Gardini over 12 years
    I changed my loop to @foreach (var item in ViewBag.EAList), and remove @ from item variable, it has the same error.
  • Jerad Rose
    Jerad Rose over 12 years
    Sorry, I was assuming the OP had already included ul/ol somewhere else. But you're right, those should wrap the li tags.
  • Andrew Barber
    Andrew Barber over 12 years
    also, while you are correct about how to make that call... that won't fix the problem. See my answer for why.
  • Andrew Barber
    Andrew Barber over 12 years
    Not var. The actual type of the collection. You can also probably add ViewBag.EAList as ActualListType to be safe.
  • Rubia Gardini
    Rubia Gardini over 12 years
    My call in controller is "ViewBag.EAList = db.EAList.ToList();" what should be my variable type in my View?
  • Jerad Rose
    Jerad Rose over 12 years
    Yeah, as Andrew said, var or dynamic should be the actual type of the elements that make up EAList. We don't know what that is in your case, so we can't give you sample code for that.
  • Andrew Barber
    Andrew Barber over 12 years
    You need to cast your dynamic objects to their actual types, @RubiaGardini
  • Paul Tyng
    Paul Tyng over 12 years
    Should be something like @foreach(YourItemClassName item in ViewBag.EAList)
  • Andrew Barber
    Andrew Barber over 12 years
    @RubiaGardini we have no idea what the type is of those objects. You need to know that.
  • Paul Tyng
    Paul Tyng over 12 years
    What is the type of EAList? You know instead of using ViewBag if you just used a Model it would simplify most of this.
  • Rubia Gardini
    Rubia Gardini over 12 years
    Well, my results come from a LINQ query... and I convert it .ToList() I don't know how should I use Model, can I make a foreach loop with that?
  • Andrew Barber
    Andrew Barber over 12 years
    You need to know what type is being output. Since you call ToList(), you know it's a List of T, but you need to replace T with the actual domain type here. What type are the items in the list?
  • Rubia Gardini
    Rubia Gardini over 12 years
    When I do this I get the error: CS1579: foreach statement cannot operate on variables of type 'MvcWebRole1.Models.DiaryPosts' because 'MvcWebRole1.Models.DiaryPosts' does not contain a public definition for 'GetEnumerator'
  • Paul Tyng
    Paul Tyng over 12 years
    Ah sorry, typo on my part in the 2nd code sample. I have ammended, it should have had IEnumerable<EAListItem> or List<EAListItem> where EAListItem is your row type...
  • Rubia Gardini
    Rubia Gardini over 12 years
    I'm very new to MVC3, Razor and EF, I can't get what class should I put inside List<> item, I have only classes generated by DBContext generator. I don´t know how to work with that in more advanced way. I solved my problem using like this: int EAID = item.EstadoDeAlmaID; @Html.Hidden("EstadoDeAlmaID", EAID ) I know its stupid but it works.
  • Paul Tyng
    Paul Tyng over 12 years
    Typically in visual studio you can hover over variables to see their types. So if you put var model = db.EAList.ToList(); in your controller, then hover over model you would see what you need to put at the top of the view.