1

I am trying to update Enum value which display Status with three value, Open, OnHold, Close

public enum TicketStatus
{
    Otvoren = 1,
    NaCekanju = 2,
    Zatvoren = 3
}

I assign this value to my Model field and give the default value of Open

public string Status { get; set; } = TicketStatus.Otvoren.ToString();

Right now the problem start when I want to update this value, and change from Open to OnHold or Close

[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Upsert(TicketVM ticketVM)
{
    var users = _unitOfwork.ApplicationUser.GetAll(x => x.Id == x.UserName);
    var userName = User.FindFirstValue(ClaimTypes.Email);
    var user = HttpContext.User.Identity.Name;

    if (ModelState.IsValid)
    {
        if (ticketVM.Ticket.Id == 0)
        {
            ticketVM.Ticket.ApplicationUser = _db.ApplicationUsers.FirstOrDefault(u => u.Email == userName);
            ticketVM.Ticket.Status = TicketStatus.Otvoren.ToString();
            _unitOfwork.Ticket.Add(ticketVM.Ticket);
        }
        else
        {
            ticketVM.Ticket.ApplicationUser = _db.ApplicationUsers.FirstOrDefault(u => u.Email == userName);
            
            _unitOfwork.Ticket.Update(ticketVM.Ticket);
        }
        _unitOfwork.Save();
        return RedirectToAction(nameof(Index));
    }
    return View(ticketVM);
}

Here is the Upsert method where Status should be updated. So far what I try is this:

Method 1

if (ticketVM.Ticket.Status == "Otvoren")
{
    ticketVM.Ticket.Status = TicketStatus.NaCekanju.ToString();
    ticketVM.Ticket.Status = TicketStatus.Zatvoren.ToString();
}
else if (ticketVM.Ticket.Status == "NaCekanju")
{
    ticketVM.Ticket.Status = TicketStatus.Otvoren.ToString();
    ticketVM.Ticket.Status = TicketStatus.Zatvoren.ToString();
}
else if(ticketVM.Ticket.Status == "Zatvoren")
{
    ticketVM.Ticket.Status = TicketStatus.Otvoren.ToString();
    ticketVM.Ticket.Status = TicketStatus.NaCekanju.ToString();
}

Method 2

if (status == "Otvoren")
{
    status = TicketStatus.Otvoren.ToString();
}
else if (status == "NaCekanju")
{
    status = TicketStatus.NaCekanju.ToString();
}
else if (status == "Zatvoren")
{
    status = TicketStatus.Zatvoren.ToString();
}

Method 3

switch (status)
{
    case "Otvoren":
        TicketStatus.Otvoren.ToString();
        break;
    case "NaCekanju":
        TicketStatus.NaCekanju.ToString();
        break;
    case "Zatvoren":
        TicketStatus.Zatvoren.ToString();
        break;
}

And here is my HTML dropdown

<div class="form-group row">
    <div class="col-4">
        <label>Status Tiketa</label>
    </div>
    <div class="col-8">
        <select asp-for="@Model.Ticket" asp-items="Html.GetEnumSelectList<VmSTicketing.Models.Enum.TicketStatus>()" class="form-control"></select>
    </div>
</div>
  • Method 1 doesn't update status at all, and value is always default as it is Open
  • Method 2 same as Method 1
  • Method 3 doesn't work at all too

My question is: How can I update value from enum dropdown menu using ?

atiyar
  • 7,762
  • 6
  • 34
  • 75
UnKnowUser
  • 133
  • 10
  • Note, I would keep `Status` a `TicketStatus` type, and only convert it ToString when I pass it to a string output. – JHBonarius Mar 15 '21 at 09:41
  • Does this answer your question? [Convert a string to an enum in C#](https://stackoverflow.com/questions/16100/convert-a-string-to-an-enum-in-c-sharp) – JHBonarius Mar 15 '21 at 09:43
  • @JHBonarius Can you write this in my example please ? – UnKnowUser Mar 15 '21 at 09:49
  • Maybe the dupe is wrong. The question is not clear. When do you want to update? What's the trigger? What is `status` (without the capital S). And do I understand that your TicketVM contains the whole Ticket Entity? Kind of defies the idea of a view model... – JHBonarius Mar 15 '21 at 09:51
  • Since you're already using the htmlhelper https://www.tutorialsteacher.com/mvc/htmlhelper-dropdownlist-dropdownlistfor – JHBonarius Mar 15 '21 at 09:51
  • @JHBonarius Yes, TicketVM containt Status. I want to update status and all other parameter in my TIcketVM entry – UnKnowUser Mar 15 '21 at 09:53
  • If you check my `Upsert` method you will see in `else` you can find something like `tickeVM.Ticket.Update()` and before this method I would like to update status as well. – UnKnowUser Mar 15 '21 at 09:54
  • But status has three value, and all three value I need to be updated. If user submit ticket it is by defaul `Open`, and As Admin User I want to change to OnHold or Close depending of what I want – UnKnowUser Mar 15 '21 at 09:55
  • According to your code there is a `status` and a `Status`. Those are different objects. It is not clear what does what and when you mean which. Be specific please. – JHBonarius Mar 15 '21 at 09:58
  • Avoid status, only Status is correct. This `status` doesn't exist in my code anymore – UnKnowUser Mar 15 '21 at 09:59
  • "depending of what I want" it is impossible for the computer to know what you want. You have to tell it what to do. From your code it is not clear what should happen in what case. Maybe you should clarify that first. – JHBonarius Mar 15 '21 at 10:00
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/229927/discussion-between-unknowuser-and-jhbonarius). – UnKnowUser Mar 15 '21 at 10:01
  • @JHBonarius By default status is assign as `Open`. And As Admin I want to update this status to `OnHold` or `Close`. `ticketVM.Ticket.Status` is only important in this time. Avoid `status` object, I deleted from my code – UnKnowUser Mar 15 '21 at 10:06

1 Answers1

3

Your HTML is not sending any value for ticket status, and the model binder is always using the default initialized value.

Change the asp-for in select tag from @Model.Ticket to @Model.Ticket.Status -

<select asp-for="@Model.Ticket.Status" asp-items="Html.GetEnumSelectList<VmSTicketing.Models.Enum.TicketStatus>()" class="form-control"></select>

This will give you the string representation of the int value you set to the enum members. You can get the enum string from that and set it to the ticket status, like -

ticketVM.Ticket.Status = ((TicketStatus)Convert.ToInt32(ticketVM.Ticket.Status)).ToString();

An alternative approach:

For create and edit operation, in your controller you have GET methods that returns the view. Create a SelectList with your enum member names and add it to the ViewBag -

public IActionResult Create()
{
    ViewBag.StatusList = new SelectList(Enum.GetNames(typeof(TicketStatus)));
    return View();
}

and in your HTML change the select tag as -

<select asp-for="@Model.Ticket.Status" asp-items="ViewBag.StatusList" class="form-control"></select>

Now you will get the enum member name selected in the dropdown as the value for ticketVM.Ticket.Status in the controller and you don't have to do anything to set this value.

atiyar
  • 7,762
  • 6
  • 34
  • 75
  • Thank you. But once I change status and when I again call method it is not display changed status. For example if I change status to `OnHold` and save action, it redirect to index page, and when I again call edit method it display previous status `Open` – UnKnowUser Mar 15 '21 at 15:15
  • @UnKnowUser Is the Status value is updating successfully? – atiyar Mar 15 '21 at 15:40
  • Yes it is updated successfully, but it doesn't save previous status. – UnKnowUser Mar 15 '21 at 18:20
  • @UnKnowUser Did it work correctly before you fix the current issue? From the answer which approach for `asp-items` did you apply - your previous existing approach or the `ViewBag.StatusList` approach? – atiyar Mar 15 '21 at 18:27
  • I implement first approach not second. – UnKnowUser Mar 15 '21 at 18:31
  • @UnKnowUser Did it work correctly before you fix the current issue? – atiyar Mar 15 '21 at 18:32
  • No, It didn't work correctly. Even before didn't works at all – UnKnowUser Mar 15 '21 at 18:33
  • 1
    @UnKnowUser Then it can depend on a lot of things. I would suggest you post another question clearly describing issue. Specifically with the code for the index page and how you are loading data for that page. – atiyar Mar 15 '21 at 18:37
  • Thank you for answer however ! I will try to find the figure out this error ! :) – UnKnowUser Mar 15 '21 at 18:40