1

I am not sure how to go about this. My ticket object, has a DateTime property called TicketCreationTime, which said property is defaulting to 1/1/0001 at 12 AM; every time it's edit entity function is called from the tickets controller.

Image showing the tickets time defaulting to the beginning of time, in its view

How could I make it, so that the TicketCreationTime stays the same as changes are made to it's ticket object? That way, the creation time is always the time as when the ticket was made?

Ticket Object

public class Ticket
{
    public int ID { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }
    public DateTime TicketCreationTime { get; set; } 
    public DateTime DueDate { get; set; }
    public DateTime TicketUpdatedTime { get; set; } 

    public Ticket()
    {
    }
}

TicketsController Create

public async Task<IActionResult> Create([Bind("ID,Name,Description,TicketCreationTime,DueDate,TicketUpdatedTime,CurrentStatus,Importance")] Ticket ticket)
{
    if (ModelState.IsValid)
    {
        DateTime StartTime = DateTime.Now;

        ticket.TicketCreationTime = StartTime;
        ticket.TicketUpdatedTime = StartTime;
        _context.Add(ticket);
        await _context.SaveChangesAsync();
        return RedirectToAction(nameof(Index));
    }
    return View(ticket);
}

TicketsController Edit

public async Task<IActionResult> Edit(int id, [Bind("ID,Name,Description,TicketCreationTime,DueDate,TicketUpdatedTime,CurrentStatus,Importance")] Ticket ticket)
{
    if (id != ticket.ID)
    {
        return NotFound();
    }

    if (ModelState.IsValid)
    {
        try
        {
            ticket.TicketUpdatedTime = DateTime.Now;
            _context.Update(ticket);
            await _context.SaveChangesAsync();
        }
        catch (DbUpdateConcurrencyException)
        {
            if (!TicketExists(ticket.ID))
            {
                return NotFound();
            }
            else
            {
                throw;
            }
        }
        return RedirectToAction(nameof(Index));
    }
    return View(ticket);
}
Peter B
  • 22,460
  • 5
  • 32
  • 69
Skilled Rook
  • 171
  • 1
  • 10

2 Answers2

2

This problem is exactly why applying the Model concept is useful, which you may also recognize as the "M" in MVC.

A Model class/object can look like an EF entity class/object, but it exists separately from actual database content.

A Model can be used to display data (you may not always want to show all data, or you may want to show it in some other way from how it is stored) and/or a Model can be used to process data that is received from the rendered web page.

In this case the Model class would have most of the properties from the Entity class, except for the Ticket....Time properties. When the Edit POST command is received, you need to retrieve the Entity object from the DbContext, update it with properties from the Model object, and then save the Entity object.

Example code:

public class TicketUpdateModel
{
    public int ID { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }
    public DateTime DueDate { get; set; }
}

[HttpPost]
public async Task<IActionResult> Edit(TicketUpdateModel model)
{
    var ticket = await _context.Tickets.FindAsync(model.ID);
    if (ModelState.IsValid)
    {
        try
        {
            ticket.TicketUpdatedTime = DateTime.Now;
            ticket.Name = model.Name;
            ticket.Description = model.Description;
            ticket.DueDate = model.DueDate;
            await _context.SaveChangesAsync();
        }
        catch (DbUpdateConcurrencyException)
        {
            // ....
        }
        return RedirectToAction(nameof(Index));
    }
    return View(ticket); // or perhaps use a TicketDisplayModel class
}
Peter B
  • 22,460
  • 5
  • 32
  • 69
  • I am still not quite sure about what to do. I am trying to keep the data contained in the TicketedCreatedTime property constant (or not have it nulled upon editing its ticket). How can I do this, as it appears when I call the edit action; this problem occurs? The Created date will not change, but the updated date will; as you can only open initially open a ticket one time. – Skilled Rook Dec 28 '21 at 23:15
  • 1
    My solution will keep it unchanged. `TicketCreationTime` is loaded along with all other properties in the FindAsync call, there is code for changing what needs to be changed but NO code that changes `TicketCreationTime`, and then the object is saved again. – Peter B Dec 28 '21 at 23:42
  • That makes more sense, how do I actually implement the model part? This is like day 3 of me using MVC stuff – Skilled Rook Dec 28 '21 at 23:48
  • 1
    The model class is in my answer, you might be able to use it as-is. It would help to do some study on the subject, you can try doing a search for tutorials on YouTube. Or for more professional teaching there is Udemy and Pluralsight. – Peter B Dec 29 '21 at 00:30
  • That worked after I messed with it a bit. Thank you for the advice. – Skilled Rook Dec 29 '21 at 00:56
0

Use DateTime? instead of DateTime for TicketCreationTime. And update it if it is null:

ticket.TicketUpdatedTime = DateTime.Now;

if (ticket.TicketCreationTime is null)
{
    ticket.TicketCreationTime = ticket.TicketUpdatedTime;
}
NightmareZ
  • 41
  • 5
  • Do I put that in the Ticket.cs object? – Skilled Rook Dec 28 '21 at 21:27
  • I tried it, it is better, but still not quite right. Now instead of the creation date being nulled when the object is edited; it is now overriding its value with that of the update date. How can I keep the original creation date the same? – Skilled Rook Dec 28 '21 at 21:40