C
C#•6mo ago
yatta

The value '' is invalid. for primary key in MVC

I'm practicing MVC with asp.net and building a simple todo app. I have my Model:
public class Todo
{
public int Id { get; set; }

public string? Name { get; set; }
}
}
public class Todo
{
public int Id { get; set; }

public string? Name { get; set; }
}
}
and MVC controller:
public IActionResult Insert()
{
return View("_Form");
}
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Insert([Bind("Id, Name")]Todo todo)
{
if (ModelState.IsValid)
{
_context.Add(todo);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
return View("_Form",todo);
}
public IActionResult Insert()
{
return View("_Form");
}
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Insert([Bind("Id, Name")]Todo todo)
{
if (ModelState.IsValid)
{
_context.Add(todo);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
return View("_Form",todo);
}
and my view _Form.cshtml:
@model Todo
<form asp-action="Insert" id="form-action" method="post" role="form">
<div asp-validation-summary="All"></div>
<label asp-for="Name"></label>
<input asp-for="Id" type="hidden" />
<input asp-for="Name" />
<span asp-validation-for="Name"></span>
<input type="submit" id ="form-button" value="Add Todo" />
</form>
@model Todo
<form asp-action="Insert" id="form-action" method="post" role="form">
<div asp-validation-summary="All"></div>
<label asp-for="Name"></label>
<input asp-for="Id" type="hidden" />
<input asp-for="Name" />
<span asp-validation-for="Name"></span>
<input type="submit" id ="form-button" value="Add Todo" />
</form>
When I try to run the program, the data is not written into my database and I also get the error The value '' is invalid , when I run the program in debug, the error cause from Id value, from what I found on the internet, people that had this error only cause with other attribute, but not primary key as mine. So I'm frustrated right now, because it's primary key, so I cannot just make it nullable or assign a default value as the normal attribute.
No description
15 Replies
yatta
yatta•6mo ago
For the primary in my database, I believe it has all the standards of a primary key
No description
Angius
Angius•6mo ago
You're adding a new todo with the primary key already defined instead of letting the database generate that key Perhaps there's some conflict, like trying to insert an item with ID that already exists
yatta
yatta•6mo ago
not likely, because there's no record ever inserted into my database, but I think it might has something to do with the id value when my method get is 0 when I try to run it ?
Angius
Angius•6mo ago
Could be I don't think 0 is a valid PK Again, it would be best if you just let the database generate them
yatta
yatta•6mo ago
how could I do that from my method? Excluding the id binding ?
x0rld
x0rld•6mo ago
you could create a custom dto for that cause the id isn't useful in your form
Angius
Angius•6mo ago
First of all, don't pass the database model around and use a DTO
yatta
yatta•6mo ago
could you give me more detail ? I dont think I understand you entirely Arrestbi
Angius
Angius•6mo ago
public record TodoDto(string Name);

public IActionResult Insert()
{
return View("_Form");
}
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Insert([FromForm]TodoDto data)
{
if (ModelState.IsValid)
{
var todo = new Todo {
Name = data.Name,
};
_context.Add(todo);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
return View("_Form",todo);
}
public record TodoDto(string Name);

public IActionResult Insert()
{
return View("_Form");
}
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Insert([FromForm]TodoDto data)
{
if (ModelState.IsValid)
{
var todo = new Todo {
Name = data.Name,
};
_context.Add(todo);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
return View("_Form",todo);
}
@model TodoDto
<form asp-action="Insert" id="form-action" method="post" role="form">
<div asp-validation-summary="All"></div>
<label asp-for="Name"></label>
<input asp-for="Name" />
<span asp-validation-for="Name"></span>
<input type="submit" id ="form-button" value="Add Todo" />
</form>
@model TodoDto
<form asp-action="Insert" id="form-action" method="post" role="form">
<div asp-validation-summary="All"></div>
<label asp-for="Name"></label>
<input asp-for="Name" />
<span asp-validation-for="Name"></span>
<input type="submit" id ="form-button" value="Add Todo" />
</form>
x0rld
x0rld•6mo ago
I'm not even sure you need the FromForm these day 🤔
yatta
yatta•6mo ago
we dont need [HttpPost] and [ValidateAntiForgeryToken] anymore ?
Angius
Angius•6mo ago
I didn't remove them
yatta
yatta•6mo ago
oh wait, mb I was Arrestbi code actually works, ty a lot, I'll try to see the different and learn thumbbi
Angius
Angius•6mo ago
+public record TodoDto(string Name);

public IActionResult Insert()
{
return View("_Form");
}
[HttpPost]
[ValidateAntiForgeryToken]
- public async Task<IActionResult> Insert([Bind("Id, Name")]Todo todo)
+ public async Task<IActionResult> Insert([FromForm]TodoDto data)
{
if (ModelState.IsValid)
{
+ var todo = new Todo {
+ Name = data.Name,
+ };
_context.Add(todo);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
return View("_Form",todo);
}
+public record TodoDto(string Name);

public IActionResult Insert()
{
return View("_Form");
}
[HttpPost]
[ValidateAntiForgeryToken]
- public async Task<IActionResult> Insert([Bind("Id, Name")]Todo todo)
+ public async Task<IActionResult> Insert([FromForm]TodoDto data)
{
if (ModelState.IsValid)
{
+ var todo = new Todo {
+ Name = data.Name,
+ };
_context.Add(todo);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
return View("_Form",todo);
}
-@model Todo
+@model TodoDto
<form asp-action="Insert" id="form-action" method="post" role="form">
<div asp-validation-summary="All"></div>
<label asp-for="Name"></label>
- <input asp-for="Id" type="hidden" />
<input asp-for="Name" />
<span asp-validation-for="Name"></span>
<input type="submit" id ="form-button" value="Add Todo" />
</form>
-@model Todo
+@model TodoDto
<form asp-action="Insert" id="form-action" method="post" role="form">
<div asp-validation-summary="All"></div>
<label asp-for="Name"></label>
- <input asp-for="Id" type="hidden" />
<input asp-for="Name" />
<span asp-validation-for="Name"></span>
<input type="submit" id ="form-button" value="Add Todo" />
</form>