skip to Main Content

I’m creating a website where you can Create an event for a game.I have a Create Page. The page has a GameID field when creating a new Event. I’m attempting to use a ViewModel so that I can display the name of the Game and select that, rather than the ID.

public class EventCreateVM
    {
        public Events Event { get; set; }
        public IEnumerable<SelectListItem> Games { get; set; }
    }
public class Events
{
    public int EventID { get; set; }
    public int GameID { get; set; }
    [DisplayName("Event Name")]
    public string EventName { get; set; }
    public string Server { get; set; }
    [DisplayName("Max Players")]
    public int MaxPlayers { get; set; }
    public string Type { get; set; }
    public string Platform { get; set; }
    public string Description { get; set; }
    [DisplayName("Event Time")]
    public DateTime DateTime { get; set; }
}

I’ve altered the Create page so that it works with the ViewModel

@model AgileTeamFour.UI.ViewModels.EventCreateVM

@{
    ViewData["Title"] = "Create";
}
<h1>Create</h1>

<h4>Events</h4>
<hr />
<div class="row">
    <div class="col-md-4">
        <form asp-action="Create" asp-controller="Event">
            <div asp-validation-summary="ModelOnly" class="text-danger"></div>
           @*  <div class="form-group">
                <label asp-for="Event.EventID" class="control-label"></label>
                <input asp-for="Event.EventID" class="form-control" />
                <span asp-validation-for="Event.EventID" class="text-danger"></span>
            </div> *@
            <div class="form-group">
    <label asp-for="Event.GameID" class="control-label"></label>
    <select asp-for="Event.GameID" class="form-control" asp-items="Model.Games"></select>
    <span asp-validation-for="Event.GameID" class="text-danger"></span>
</div>
            <div class="form-group">
                <label asp-for="Event.EventName" class="control-label"></label>
                <input asp-for="Event.EventName" class="form-control" />
                <span asp-validation-for="Event.EventName" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Event.Server" class="control-label"></label>
                <input asp-for="Event.Server" class="form-control" />
                <span asp-validation-for="Event.Server" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Event.MaxPlayers" class="control-label"></label>
                <input asp-for="Event.MaxPlayers" class="form-control" />
                <span asp-validation-for="Event.MaxPlayers" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Event.Type" class="control-label"></label>
                <input asp-for="Event.Type" class="form-control" />
                <span asp-validation-for="Event.Type" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Event.Platform" class="control-label"></label>
                <input asp-for="Event.Platform" class="form-control" />
                <span asp-validation-for="Event.Platform" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Event.Description" class="control-label"></label>
                <input asp-for="Event.Description" class="form-control" />
                <span asp-validation-for="Event.Description" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Event.DateTime" class="control-label"></label>
                <input asp-for="Event.DateTime" class="form-control" />
                <span asp-validation-for="Event.DateTime" class="text-danger"></span>
            </div>
            <div class="form-group">
                <input type="submit" value="Create" class="btn btn-primary" />
            </div>
        </form>
    </div>
</div>

<div>
    <a asp-action="Index">Back to List</a>
</div>

@section Scripts {
    @{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}

And altered the controller.


public ActionResult Create()
{
    var games = GameManager.Load(); 
    var viewModel = new EventCreateVM
    {
        Event = new Events(),
        Games = games.Select(g => new SelectListItem
        {
            Value = g.GameID.ToString(),
            Text = g.GameName
        }).ToList()
    };
    return View(viewModel);
}

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(EventCreateVM viewmodel)
{
    try
    {
        if (ModelState.IsValid)
        {
            int eventID = 0;
            EventManager.Insert(ref eventID, viewmodel.Event.GameID, viewmodel.Event.EventName, viewmodel.Event.Server, viewmodel.Event.MaxPlayers, viewmodel.Event.Type, viewmodel.Event.Platform, viewmodel.Event.Description, viewmodel.Event.DateTime);
            return RedirectToAction(nameof(Index));
        }
        return View(viewmodel);
    }
    catch
    {
        return View();
    }
}

The page makes the Game select list fine. But when I try pushing the submit button, the page just refreshes and it doesn’t create anything in the database.

The payload form seems fine, as far as I can tell. The post is 200 and doesn’t seem to encounter an error. The create function works fine if I’m not using the viewmodel changes. I’ve been trying for a few hours to figure it out but haven’t had any luck. Any advice would be greatly appreciated.

2

Answers


  1. Based on your code, the request is sent to the "Event/Create" API with GET instead of POST (HTTP method) when the form is submitted.

    You can debug by placing the breakpoint in the first line of code for both "Event/Create" API (methods) with GET and POST. This will help you to determine whether the "Event/Create" API (with POST method) is hit.

    In summary, add the method="POST" attribute to the <form> element to ensure that the form is submitted to the right API.

    <form asp-action="Create" asp-controller="Event" method="POST">
        ...
    </form>
    
    Login or Signup to reply.
  2. Try to set break point in the Create Post method, you can find out the issue relates the ModelState and Games Property is inValid:

    model invalid

    The issue relates the Nullable Reference Types

    To solve this issue, you can set the Games property as nullable:

    public class EventCreateVM
    {
        public Events Event { get; set; }
        public IEnumerable<SelectListItem>? Games { get; set; }  
    }
    

    Or set an initial value.

    public class EventCreateVM
    {
        public Events Event { get; set; }
        public IEnumerable<SelectListItem> Games { get; set; }  = new List<SelectListItem>();
    }
    

    Then, the result as below:

    success

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search