I have an ASP.NET Core 6 MVC application.
On one page I have a table; I want to support drag'n'drop for its rows. Afterwards the User is able to click on "Submit" and make the changes permanent.
The changes are sent to the controller and persisted to the database, however when I redirect to the GET to show the page again, a part of it is wrong!
@model MyViewModel
<form>
@Html.HiddenFor(y=>y.Id)
<table id="orderTable" class="table">
<thead>
<tr>
<th>
Name
</th>
<th>
Order
</th>
</tr>
</thead>
<tbody>
@foreach (var data in Model.Data)
{
<tr id='@data.Id'>
<td>@data.Name</td>
<td>@data.Order</td>
</tr>
}
</tbody>
</table>
<div class="form-group">
<input type="submit" value="Save" id="SaveOrderButton" />
</div>
</form>
<script>
$(document).ready(function() {
$('#orderTable tbody').sortable();
$("#SaveOrderButton").click(function(e) {
e.preventDefault();
var newOrder = $('#orderTable tbody').sortable('toArray');
$.ajax({
url: '/Controller/Update',
type: 'POST',
data: { rowOrder: newOrder, id: @Html.Raw(Model.Id) },
success: function(response) {
console.log(response);
},
error: function(xhr,status, error){
console.log("An error occurred: " + xhr.responseText);
}
});
});
});
</script>
Backend:
[HttpGet]
public async Task<IActionResult> Order(int id)
{
var data= await context.Data
.AsNoTracking()
.Where(x => x.Id== id)
.ToListAsync();
data = data.OrderByDescending(y => y.Order.HasValue)
.ThenBy(y => y.Order)
.ToList();
var viewModel = new MyViewModel()
{
Data = data,
Id = id,
};
ModelState.Clear(); // found on SO, but does not change anything
return View(viewModel);
}
[HttpPost]
public async Task<IActionResult> Update(int[] rowOrder, int id)
{
var data= await context.Data
.Where(y => rowOrder.Contains(y.Id))
.ToListAsync();
for (int i = 0; i < rowOrder.Count(); i++)
{
data.First(y => y.Id == rowOrder[i]).Order = i;
}
try
{
context.UpdateRange(data);
await context.SaveChangesAsync();
}
catch (Exception ex)
{
logger.LogError("..........");
return Json(500, "Could not update new order.");
}
return RedirectToAction(nameof(Controller.Order), new { id= id});
}
Okay, so I go the the view with GET and everything is shown correctly, then I change something and click on "Save". Everything in the POST will be correctly done. The database is updated.
I then redirect to the GET method again, there everything is loaded correctly from the database and in the correct order.
Then I set a breakpoint in the View and there the stuff in the for is correct too.
However, when I look in the browser, the "Order" column is wrong. The table still shows the data how it looked like after I reordered it and before I clicked on "Save".
What is happening here? Is the sortable lib using a cache in the background that I have to invalidate?
I don't use a cache anywhere in my project, btw.
Also, when I go to the console after a POST, the whole website's HTML is in there.
When I now reload the page with the GET, everything is shown how it is supposed to be.
Has it something to do with Ajax? I have already removed the success and error events, which doesn't change anything.