1

I have an asp.net mvc application. I want to perform and update operation.I want to show you my code before explain my problem sorry I am not fluent in english thats why I prefer to show my code first.Here I have an index page that shows all items in database with a table

 @model IEnumerable<InOut.Models.Item>
@if (Model.Count() > 0)
{
    <table class="table table-bordered table-striped" style="width: 100%; text-align: center">
        <thead>
        <tr>
            <th>Item Name</th>
            <th>Borrower</th>
            <th>Lender</th>
            <th >Edit</th>
        </tr>
        </thead>
        <tbody>
        @foreach (var item in Model)
        {
            <tr>
                <td style="width: 25%">@item.borrower</td>
                <td style="width: 25%">@item.Lender</td>
                <td style="width: 25%">@item.ItemName</td>
                <td style="width: 13%">
                    <a asp-controller="Item" asp-action="Delete" asp-route-id="@item.id"  onclick="showAlert()"class="btn btn-danger" id="btn1" style="text-decoration: none; color: white">delete</a>
                    <a asp-controller="Item" asp-action="Update" asp-route-id="@item.id"  class="btn btn-primary" id="btn1" style="text-decoration: none; color: white">Update</a>
                </td>
            </tr>
        }
        </tbody>
    </table>
}
else
{
    <p> No Items created </p>
 }

Here is the index action for that view

  public IActionResult Index()
{
    IEnumerable<Item> items = _dbContext.Items;
    return View(items);
}

In the foreach loop I have a button to update the object on that row it has an action named "Update" in controller class.here is the code to get the item on that row.

//Get Item
public IActionResult Update(int? id)
{
    var item = _dbContext.Items.Single(o => o.id == id);
    return View(item);
}

this action sends the selected item properties to the update view.here is the code of view

<form method="post" asp-action="Create">
<input asp-for="id" hidden/>
<div class="form-group">
    <label >Item Name </label>
    <input type="text" class="form-control" aria-describedby="emailHelp" asp-for="ItemName">
</div>
<div class="form-group">
    <label >Borrower</label>
    <input type="text" class="form-control" asp-for="borrower">
</div>
<div class="form-group">
    <label >Lender</label>
    <input type="text" class="form-control" asp-for="Lender">
</div>

<button asp-controller="Item" asp-action="Update" type="submit" class="btn btn-primary" style="margin-top: 10px">Submit</button>

submit button sends properties to the overloaded action update with the parameter of item. after update operation I want it to show me the index page. here is the overloaded update action

  // Update Item 
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Update(Item item)
{
    _dbContext.Update(item);
    _dbContext.SaveChanges();
    return View("Index");
}

Problem starts here. When I run application after submitting changes I want it to show me the index action update operation working well.but when it try to show me the index page it gives me this error.

ArgumentNullException: Value cannot be null. (Parameter 'source') and it refers to the if statement in the index page it

now if I use redirectToAction return instead of View like this...

 [HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Update(Item item)
{
    _dbContext.Update(item);
    _dbContext.SaveChanges();
    return RedirectToAction("Index");
}

It works as I wanted. I want to know what is the problem with the first approach and is there any difference between those 2 return types?

Sait POSTACI
  • 97
  • 1
  • 2
  • 5
  • Does this answer your question? [What is a NullReferenceException, and how do I fix it?](https://stackoverflow.com/questions/4660142/what-is-a-nullreferenceexception-and-how-do-i-fix-it) – madreflection Feb 15 '22 at 19:24
  • Although this question is about `ArgumentNullException`, the same diagnostic principles as for `NullReferenceException` apply since it's on an extension method call. – madreflection Feb 15 '22 at 19:24
  • 2
    The former renders view directly from update, it's an antipattern. Later redirects and it's [correct](https://en.wikipedia.org/wiki/Post/Redirect/Get). Don't even try to fix the former. But if you want, you seem to lack the model. – Wiktor Zychla Feb 15 '22 at 19:26
  • okay thank you sir it is makes sense now – Sait POSTACI Feb 15 '22 at 19:32

1 Answers1

0

the difference is here

  public IActionResult Index()
{
 IEnumerable<Item> items = _dbContext.Items; //maybe you need to add .ToList(); ??
    return View(items);
}

when you are using an index action you create the list of items as a model and pass them to the view. But you don't create any model when you call Index view from an update action. If you still want to return view from an update you can do it this way

_dbContext.Update(item);
    _dbContext.SaveChanges();
 var  items = _dbContext.Items.ToList();
    return View("Index", items);

or if update and index actions are in the same controller I usually just call an action as a method

_dbContext.Update(item);
    _dbContext.SaveChanges();

    return Index();
Serge
  • 40,935
  • 4
  • 18
  • 45