mmssaann
mmssaann

Reputation: 1507

Call post edit action from Razor view mvc4

This question might have been asked several times, however it is not working in my case, so please bear with me.

I have the below actions in my controller:

    [HttpPost]
    public ActionResult Edit(Organization obj)
    {
        if (ModelState.IsValid)
        {
            OrgRepo.Update(obj);
            return RedirectToAction("Details");
        }
        else
            return View();
    }

    public ActionResult Edit(int id)
    {
        return View();
    }

I am trying to update the data into database by calling post edit action. For this purpose, I am calling the edit action as below:

@foreach (var item in Model) {

var test =  item.PartyId;  

<tr id="@test">
    <td  class ="txt">
        <input type="text"class="txt" value="@Html.DisplayFor(modelItem => item.Caption)"/>

    </td>
    <td class ="txt">
        <input type="text"class="txt" value="@Html.DisplayFor(modelItem => item.NameInUse)"/>
    </td>
    <td class ="txt">
        <input type="text"class="txt" value="@Html.DisplayFor(modelItem => item.Description )"/>
   </td>
   <td>
       @using (Html.BeginForm())
        {
            @Html.ActionLink("Edit", "Edit", "Org", null, new { @obj = item })
        }
    </td>
</tr>

However when I click on edit I am getting exception: The parameters dictionary contains a null entry for parameter 'id' of non-nullable type 'System.Int32' for method 'System.Web.Mvc.ActionResult Edit(Int32)' in 'Dwiza.Controllers.OrgController'. An optional parameter must be a reference type, a nullable type, or be declared as an optional parameter. Parameter name: parameters

My questions:

  1. How can I fix this?
  2. Why it get edit action is getting invoked instead of post edit?
  3. What are better ways to invoke edit action among invoke through jQuery, or ajax or any others, if you can suggest better ways of doing it?

Upvotes: 0

Views: 5679

Answers (2)

Sean Kenny
Sean Kenny

Reputation: 1636

The @Html.ActionLink produces an a tag which can only be used to call GET. Change to a submit button to get a POST.

Normally with an Edit, you are only editing a sinble model rather than a collection on a page but going with what you have, change the cshtml to:

@model ICollection<Organization>

<table>
@foreach (var item in Model)
{
    using (Html.BeginForm())
    {
        var test = item.PartyId;

    <tr id="@test">
        <td class="txt">
            <input type="text" name="Caption" class="txt" value="@item.Caption"/>
        </td>
        <td class="txt">
            <input type="text" name="NameInUse" class="txt" value="@item.NameInUse"/>
        </td>
        <td class="txt">
            <input type="text" name="Description" class="txt" value="@item.Description" />
        </td>
        <td>
            <input type="hidden" name="PartyId" value="@item.PartyId"/>
            <button type="submit">Edit</button>
        </td>
    </tr>
    }
}
</table>

Now each table row is wrapped by a form meaning the submit button will post that data. The name attribute on the inputs will cause the MVC model binders to bind your posted values to your model correctly.

This hidden input at the end will ensure your PartyId value gets posted back. The fact that it is in int (and not nullable) was giving the exception with your initial code I think.

HTH

EDIT

Adding controller code (note - I still think this is a little/lot strange as you should be editing only the one Organisation...

public ActionResult Edit(int id)
{
    // get your organisations from your orgRepo...  I'm mocking that out.
    var orgs = new List<Organization> { new Organization { PartyId = 1, Description = "Org 1", Caption = "Caption 1", NameInUse = "Name 1"},
                                        new Organization { PartyId = 2, Description = "Org 2", Caption = "Caption 2", NameInUse = "Name 2"}};
    return View(orgs);
}

Upvotes: 2

Slicksim
Slicksim

Reputation: 7172

lordy, that is a mess dude. your form only has a link in it, and that link is to the edit action, that will invoke a get, the form will never post back. are you trying to do a form inside a table row?

@foreach (var item in Model) {

var test =  item.PartyId;  

<tr>
<td colspan ="4>
@using (Html.BeginForm("Edit", "Org", FormMethod.Post))
{
    @Html.HiddenFor(modelItem  => item.PartyId)
    <table>
        <tr  id="@test">
            <td  class ="txt">
                <input type="text"class="txt" value="@Html.DisplayFor(modelItem => item.Caption)"/>

            </td>
            <td class ="txt">
                <input type="text"class="txt" value="@Html.DisplayFor(modelItem => item.NameInUse)"/>
            </td>
            <td class ="txt">
                <input type="text"class="txt" value="@Html.DisplayFor(modelItem => item.Description )"/>
           </td>
           <td>
               <input type="submit" value="edit" />

            </td>

        </tr>
    </table>
}
</td>
</tr>   
}

That code will do an edit inside a row, but i am just guessing at the structure from the code you posted.

Upvotes: 0

Related Questions