C
C#3mo ago
morry329#

Edit function does not work

So I would like a second set of eyes. I wanted to try editing the pre-existing record on my card view (see the screenshot attached) like Beachfront Villa -> Beachfront Villa 8. Even this easy modification does not succeed, as on clicking the save button I got "record not found" And this comes from here in the controller
[HttpPost]
public async Task<IActionResult> Update(ListingProjects updatedUserModelRef)
{


if (oldListingProjects == null)
{
if (Request.Headers["X-Requested-With"] == "XMLHttpRequest")
{
return Json(new { success = false, message = "Record not found." }); //this is the error i see on View
}
return NotFound();
}
[HttpPost]
public async Task<IActionResult> Update(ListingProjects updatedUserModelRef)
{


if (oldListingProjects == null)
{
if (Request.Headers["X-Requested-With"] == "XMLHttpRequest")
{
return Json(new { success = false, message = "Record not found." }); //this is the error i see on View
}
return NotFound();
}
and this is what the frontend devtool says: https://imgur.com/a/xs8LLlD my database has not the id "1" referred in that devtool:
mysql> Select * from ListingDBTable;
+----+----------------------+----------------------------------+------------+------------+
| Id | ListingName | ImageUrl | CategoryId | LocationId |
+----+----------------------+----------------------------------+------------+------------+
| 5 | Beachfront Villa | http://example.com/villa.jpg | 1 | 1 |
| 6 | hidden moon building | hiddenmoon | 1 | 1 |
| 74 | New Listing | http://example.com/new_image.jpg | 1 | 1 |
+----+----------------------+----------------------------------+------------+------------+
mysql> Select * from ListingDBTable;
+----+----------------------+----------------------------------+------------+------------+
| Id | ListingName | ImageUrl | CategoryId | LocationId |
+----+----------------------+----------------------------------+------------+------------+
| 5 | Beachfront Villa | http://example.com/villa.jpg | 1 | 1 |
| 6 | hidden moon building | hiddenmoon | 1 | 1 |
| 74 | New Listing | http://example.com/new_image.jpg | 1 | 1 |
+----+----------------------+----------------------------------+------------+------------+
` my save button on View should have been picking up any ids listed here (5,6, or 74) but as the devtool shows it picks up 1 instead. i suppose if it picks up 5,6,74 it will let me edit the ListingName property. so could anyone kindly point me in the right direction? Relevant code snippets here https://pastebin.com/9U9zjvaG
Pastebin
/Controller/ public IActionResult Edit(int? Id) { if (I...
Pastebin.com is the number one paste tool since 2002. Pastebin is a website where you can store text online for a set period of time.
10 Replies
Angius
Angius3mo ago
What is ListingProject?
Angius
Angius3mo ago
Does it have only and exactly those properties?
No description
Angius
Angius3mo ago
public class ListingProject
{
public int Id { get; set; }
public string ListingName { get; set; }
public string __RequestVerificationToken { get; set; }
}
public class ListingProject
{
public int Id { get; set; }
public string ListingName { get; set; }
public string __RequestVerificationToken { get; set; }
}
?
morry329#
morry329#OP3mo ago
Not at all In my IDE the ListingProject has properties as follows
public class ListingProjects
{
[Key]
public int? Id { get; set; } // Primary key

[Required]
public string? ListingName { get; set; }

[Required]
public string? ImageUrl { get; set; }

[Required]
public int? CategoryId { get; set; }
public Category? Category { get; set; }

[Required]
public int? LocationId { get; set; }
public Location? Location { get; set; }

public ListingProjectsDTO? ListingProjectsDTO { get; set; } // Navigation property
}
public class ListingProjects
{
[Key]
public int? Id { get; set; } // Primary key

[Required]
public string? ListingName { get; set; }

[Required]
public string? ImageUrl { get; set; }

[Required]
public int? CategoryId { get; set; }
public Category? Category { get; set; }

[Required]
public int? LocationId { get; set; }
public Location? Location { get; set; }

public ListingProjectsDTO? ListingProjectsDTO { get; set; } // Navigation property
}
it is strange for me that my app thinks my listingProject class looks like that public class ListingProject { public int Id { get; set; } public string ListingName { get; set; } public string __RequestVerificationToken { get; set; } }` I have no idea why. Do you have idea?
Angius
Angius3mo ago
It's not strange That's the data you submit The database models should never leave the application's boundary
morry329#
morry329#OP3mo ago
Can you help me understand why my code submitted this data? I mean this
public class ListingProject
{
public int Id { get; set; }
public string ListingName { get; set; }
public string __RequestVerificationToken { get; set; }
}
public class ListingProject
{
public int Id { get; set; }
public string ListingName { get; set; }
public string __RequestVerificationToken { get; set; }
}
` Not this
public class ListingProjects
{
[Key]
public int? Id { get; set; } // Primary key

[Required]
public string? ListingName { get; set; }

[Required]
public string? ImageUrl { get; set; }

[Required]
public int? CategoryId { get; set; }
public Category? Category { get; set; }

[Required]
public int? LocationId { get; set; }
public Location? Location { get; set; }

public ListingProjectsDTO? ListingProjectsDTO { get; set; } // Navigation property
}
public class ListingProjects
{
[Key]
public int? Id { get; set; } // Primary key

[Required]
public string? ListingName { get; set; }

[Required]
public string? ImageUrl { get; set; }

[Required]
public int? CategoryId { get; set; }
public Category? Category { get; set; }

[Required]
public int? LocationId { get; set; }
public Location? Location { get; set; }

public ListingProjectsDTO? ListingProjectsDTO { get; set; } // Navigation property
}
` Can you also help me understand why my database model left the application's boundary? I just would like more clarity in that
Angius
Angius3mo ago
Your code submitted this data, because it's what you told it to submit:
No description
Angius
Angius3mo ago
And the database model left the boundary when you used it as input expected by the API endpoint:
No description
morry329#
morry329#OP3mo ago
public IActionResult Update(ListingProjects updatedUserModelRef)
{
var oldListing = _context.ListingDBTable.FirstOrDefault(e => e.Id == updatedUserModelRef.Id);
if (oldListing == null)
{
// Handle the case where no record is found (e.g., return an error message)
return NotFound(); // Assuming you have a NotFound action
}
_context.Entry(oldListing).CurrentValues.SetValues(updatedUserModelRef);
_context.SaveChanges();
return RedirectToAction("TestDashboard1");
}
public IActionResult Update(ListingProjects updatedUserModelRef)
{
var oldListing = _context.ListingDBTable.FirstOrDefault(e => e.Id == updatedUserModelRef.Id);
if (oldListing == null)
{
// Handle the case where no record is found (e.g., return an error message)
return NotFound(); // Assuming you have a NotFound action
}
_context.Entry(oldListing).CurrentValues.SetValues(updatedUserModelRef);
_context.SaveChanges();
return RedirectToAction("TestDashboard1");
}
` I rewrote the code like this. does the database model leave the "boundary" with this snippet too?
Angius
Angius3mo ago
// database model
public class Person
{
public int Id { get; set; }
public string Name { get; set; }
public string Surname { get; set; }
public DateTime Birthday { get; set; }
public string PID { get; set; }
}
// database model
public class Person
{
public int Id { get; set; }
public string Name { get; set; }
public string Surname { get; set; }
public DateTime Birthday { get; set; }
public string PID { get; set; }
}
// DTO
public class PersonDto
{
public string Name { get; set; }
public string Surname { get; set; }
public DateTime Birthday { get; set; }
}
// DTO
public class PersonDto
{
public string Name { get; set; }
public string Surname { get; set; }
public DateTime Birthday { get; set; }
}
[HttpPost("edit")]
public async Task<IActionResult> Update(PersonDto data)
{
var person = await _context.People
.Where(p => p.Id == /* get user id somehow */)
.FirstOrDefaultAsync();

if (person is null) return NotFound();

person.Name = data.Name;
person.Surname = data.Surname;
person.Birthday = data.Birthday;

await _context.SaveChangesAsync();
}
[HttpPost("edit")]
public async Task<IActionResult> Update(PersonDto data)
{
var person = await _context.People
.Where(p => p.Id == /* get user id somehow */)
.FirstOrDefaultAsync();

if (person is null) return NotFound();

person.Name = data.Name;
person.Surname = data.Surname;
person.Birthday = data.Birthday;

await _context.SaveChangesAsync();
}
The action takes a DTO in this case, not the database entity
[HttpPost("{id:int}")]
public async Task<ActionResult<PersonDto>> Get(int Id)
{
var person = await _context.People
.Where(p => p.Id == /* get user id somehow */)
.Select(p => new PersonDto {
Name = p.Name,
Surname = p.Surname,
Birthday = p.Birthday,
})
.FirstOrDefaultAsync();

if (person is null) return NotFound();

return Ok(person);
}
[HttpPost("{id:int}")]
public async Task<ActionResult<PersonDto>> Get(int Id)
{
var person = await _context.People
.Where(p => p.Id == /* get user id somehow */)
.Select(p => new PersonDto {
Name = p.Name,
Surname = p.Surname,
Birthday = p.Birthday,
})
.FirstOrDefaultAsync();

if (person is null) return NotFound();

return Ok(person);
}
In this case, we return that DTO instead of returning a database entity Each action can have its own DTO, you don't need to reuse them If the Get action should not be returning the birthday, for example, just make another DTO that only has the name and the surname (DTO — Data Transfer Object)

Did you find this page helpful?