Ole Kristian Losvik Ole Kristian Losvik - 1 month ago 12
ASP.NET (C#) Question

New ASP.net core project with scaffolded edit controller just return 404 page not found

Just trying a new asp.net core project, based on the asp.net core web application template with individual user accounts.
The code below is for list definitions, and viewing and creating works fine, however - when I try to save the edits, there is just a blank page coming up. In the console I find no error messages: Only 404 Page Not Found.

The model

public class Listdefinition
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
[Key]
[ScaffoldColumn(false)]
public Guid Id { get; set; }
public Guid UserGuid { get; set; }

public string Name { get; set; }
public virtual ICollection<Listitem> ListItems { get; set; }
}


The view

<form asp-action="Edit">
<div class="form-horizontal">
<h4>Listdefinition</h4>
<hr />
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<input type="hidden" asp-for="Id" />
<div class="form-group">
<label asp-for="Name" class="col-md-2 control-label"></label>
<div class="col-md-10">
<input asp-for="Name" class="form-control" />
<span asp-validation-for="Name" class="text-danger" />
</div>
</div>
<div class="form-group">
<label asp-for="UserGuid" class="col-md-2 control-label"></label>
<div class="col-md-10">
<input asp-for="UserGuid" class="form-control" />
<span asp-validation-for="UserGuid" class="text-danger" />
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Save" class="btn btn-default" />
</div>
</div>
</div>
</form>


The controller

namespace losol.ListR.Controllers
{
public class ListdefinitionsController : Controller
{
private readonly ApplicationDbContext _context;

public ListdefinitionsController(ApplicationDbContext context)
{
_context = context;
}
// Some code emitted for brevity

// GET: ListDefinitions/Edit/5
public async Task<IActionResult> Edit(Guid? id)
{
if (id == null)
{
return NotFound();
}

var listDefinition = await _context.ListDefinition.SingleOrDefaultAsync(m => m.Id == id);
if (listDefinition == null)
{
return NotFound();
}
return View(listDefinition);
}
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(Guid id, [Bind("Name,UserGuid")] Listdefinition listdefinition)
{
if (id != listdefinition.Id)
{
return NotFound();
}

if (ModelState.IsValid)
{
try
{
_context.Update(listdefinition);
await _context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!ListdefinitionExists(listdefinition.Id))
{
return NotFound();
}
else
{
throw;
}
}
return RedirectToAction("Index");
}
return View(listdefinition);
}


And the route:

app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});


EDIT: Just found this error message:


Executing action method losol.ListR.Controllers.ListDefinitionsController.Edit (losol.ListR)
with arguments (f7ddb55a-398c-4212-b686-49c88550a26f,
losol.ListR.Models.ListDefinition) - ModelState is Valid info:
Microsoft.EntityFrameworkCore.Storage.Internal.RelationalCommandBuilderFactory[1]
Executed DbCommand (0ms) [Parameters=[@p2='?', @p0='?' (Size = 4000), @p1='?'], CommandType='Text', CommandTimeout='30']
SET NOCOUNT ON;
UPDATE [ListDefinition] SET [Name] = @p0, [UserGuid] = @p1
WHERE [Id] = @p2;
SELECT @@ROWCOUNT; fail: Microsoft.EntityFrameworkCore.DbContext[1]
An exception occurred in the database while saving changes.
Microsoft.EntityFrameworkCore.DbUpdateConcurrencyException: Database operation expected to affect 1 row(s) but actually affected 0
row(s). Data may have been modified or deleted since entities were
loaded. See http://go.microsoft.com/fwlink/?LinkId=527962 for
information on understanding and handling optimistic concurrency
exceptions.

Answer

The code you've posted would 404 in a browser because it lacks a [HttpGet] method. You said you omitted code but that would be the most important code to not omit in regards to your question.

UPDATE

I think the issue is the type you are trying to bind to in your edit action. You are specifying a Guid? when it should be int? or string? based on the example // GET: ListDefinitions/Edit/5. Maybe the comment just hasn't been updated? I'd try changing that type to string? id or int? id and debug to see if navigating the route enters the action and if a value exists for id or not, then once you get that working, attempt switching it to Guid. If you are really trying to use Guids, try changing to this:

Change controller to have route prefix attribute:

[RoutePrefix("listdefinitions")]
public class ListdefinitionsController : Controller

Change action to specify route and type of id:

[Route("edit/{id:guid}"]
[HttpGet]
[AllowAnonymous]
public async Task<IActionResult> Edit(Guid? id)

Debug web API, set a breakpoint in the controller, and attempt to hit http://localhost:/listdefinitions/edit/95dde7f309414b94bbc20b4d6b728d9f in browser to see if the guid is getting bound correctly to your action. With web api you have to be careful to never have two routes that both match the same incoming request or it will all blow up.

Comments