Bryuk
Bryuk

Reputation: 3345

How to get into the Action and passed parameters based on the button click in MVC?

UPDATE Ok, I got point that I move in wrong direction=) So, the Idea:

I have a table on my page (View = Index.cshtml):

<tbody id="SessionListBody">

<tr style="display: none;"> … </tr>
<tr>
    <td id="2" class="date"> … </td>
    <td> … </td>
    <td>
        <a class="btn btn-primary btn-sm" href="/Home/MattersSession/2"> … </a>
    </td>
</tr>
<tr>
    <td id="3" class="date"> … </td>
    <td> … </td>
    <td>
        <a class="btn btn-primary btn-sm" href="/Home/MattersSession/3"> … </a>
    </td>
</tr>
<tr>
    <td id="4" class="date"> … </td>
    <td> … </td>
    <td>
        <a class="btn btn-primary btn-sm" href="/Home/MattersSession/4"> … </a>
    </td>
</tr>
<tr>
    <td id="5" class="date"> … </td>
    <td> … </td>
    <td>
        <a class="btn btn-primary btn-sm" href="/Home/MattersSession/5"> … </a>
    </td>
</tr>
<tr>
    <td id="6" class="date"> … </td>
    <td> … </td>
    <td>
        <a class="btn btn-primary btn-sm" href="/Home/MattersSession/6"> … </a>
    </td>
</tr>

Every row contains button. I need to get the id of the first td of the row when button was clicked and pass this id to my action:

public ActionResult MattersSession(int sessionPageID)
        {
            DBAccess dba = new DBAccess();
            DataTable dt = dba.GetSessionPage(sessionPageID);
            Session["SourceFileID"] = dt.Rows[0]["SourceFileID"];
            Session["SessionPageID"] = sessionPageID;

            // Generate Table and pass it to the View
            ViewData["MattersTable"] = dt.Rows[0]["MainTableBody"];
            ViewData["SummaryTable"] = dt.Rows[0]["SummaryBody"];

            return View("Matters");
        }

Now when I click links I'm getting this error:

The parameters dictionary contains a null entry for parameter 'sessionPageID' of non-nullable type 'System.Int32' for method 'System.Web.Mvc.ActionResult MattersSession(Int32)' in 'QuickbookUploadFromElite3e.Controllers.HomeController'. An optional parameter must be a reference type, a nullable type, or be declared as an optional parameter.
Parameter name: parameters

But I need this parameter to call this method DataTable dt = dba.GetSessionPage(sessionPageID);, so if I will do this param optional, it's going to be comile error?

Upvotes: 1

Views: 562

Answers (2)

solidau
solidau

Reputation: 4081

I'm going to make a few assumptions in my answer. Please let me know if any of these assumptions are incorrect and I will adjust my answer:

  1. You are using Bootstrap
  2. These buttons are going to load a new page (essentially a GET request)
  3. You are making your rows from a strongly-typed (IEnumerable) view You use ViewData

If all of these assumptions are true, I would solve it by using an anchor link and just give it the appearance of a button. Use the View's model to get the ID for each item.

@foreach(var item in ViewData["MattersTable"]){
<tr>
    <td id="@item.Id" class="date"> … </td>
    <td> … </td>
    <td>
        <a class="btn btn-primary btn-sm" href="/myController/MattersSession/@item.Id"> "Button" Text </a>
    </td>
</tr>
}

Furthermore, you are getting the null parameter error because your routes are probably set up like {controller}/{action}/{id} so it assumes that anything in the 3rd segment will be bound by a parameter named id, but you have named your parameter in your action method SessionPageId so it cannot find the binding.

Upvotes: 2

Roman Pushkin
Roman Pushkin

Reputation: 6079

I don't see your action method attributes, but I can guess it's because of missing [HttpPost]. Try to modify your code in this way:

[HttpPost]
public ActionResult MattersSession(int sessionPageID)
{   
    return View("Matters");
}

Another reason: you may have [ValidateAntiforgetyToken] attribute. If so, it won't work, because you're not passing antiforgery token with ajax.

Upvotes: 0

Related Questions