Welcome to the Treehouse Community
Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.
Looking to learn something new?
Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.
Start your free trialDerek Vha
10,452 PointsC# MVC - View keeps hitting my GET method and not my POST method
Hi,
I am creating a .Net Core MVC Gym Booking Application.
I have a HTTPGET Method called BookClass, which displays a list of available classes. When the user selects which class they want to book, I have another method called BookClassConfirmed which is my HTTPPOST method.
However my post method doesn't seem to be hit and I've spent some time trying to figure out why but to no avail.
Here is my View:
@model IEnumerable<GymTracker.ViewModel.MemberClassViewModel>
@{
ViewData["Title"] = "BookClass";
}
<h2>Book Class</h2>
@*<div class="form-group">
<label asp-for="ClassName" class="col-md-2 control-label"></label>
<div class="col-md-10">
<select asp-for="Classname" asp-items="@Model"></select>
</div>
</div>*@
@foreach (var item in Model)
{
<form action="/Form" method="post">
<div>
<hr />
<dl class="dl-horizontal">
<dt>
@Html.DisplayNameFor(model => model.ClassName)
</dt>
<dd>
@Html.DisplayFor(modelItem => item.ClassName)
</dd>
<dt>
<a asp-action="BookClassConfirmed">Book this Class</a> |
</dt>
</dl>
</div>
</form>
}
Here is my HttpGetMethod
[HttpGet]
public async Task<IActionResult> BookClass(int id)
{
List<MemberClassViewModel> memberClassViewModel = new List<MemberClassViewModel>();
var classlist = _context.Classes.OrderBy(c=>c.ClassName).Select(x => new { Id = x.Id, Value = x.ClassName });
var listData = await (from Classes in _context.Classes
select new
{
Classes.Id,
Classes.ClassName,
Classes.MemberID
}
).ToListAsync();
listData.ForEach(x =>
{
MemberClassViewModel Obj = new MemberClassViewModel();
Obj.ClassID = x.Id;
Obj.MemberID = id;
Obj.ClassName = x.ClassName;
//Obj.ClassName = new Microsoft.AspNetCore.Mvc.Rendering.SelectList(classlist, "Id", "Value");
memberClassViewModel.Add(Obj);
}
);
return View(memberClassViewModel);
}
And here is my POST method:
[HttpPost]
public async Task<ActionResult> BookClassConfirmed(MemberClassViewModel memberClassViewModel)
{
if (_context.Classes.Where(c => c.Id == memberClassViewModel.ClassID).Any())
{
var classToBook = _context.Classes.Find(memberClassViewModel.ClassID);
classToBook.NumberOfBookings = classToBook.NumberOfBookings + 1;
_context.SaveChanges();
}
return RedirectToAction("Details");
}
Any ideas? I would have thought the asp-action="BookClassConfirmed" in my View would then redirect back to that action method (which is my POST method) but that doesnt seem to work.
Thanks
2 Answers
Steven Parker
231,269 PointsI think all "asp-action" does for you is to help create the "href" setting. But I don' think you can make a link generate a POST operation like you can with a form submit. I'm pretty sure links always use GET. So even if it's routed correctly, the [HttpPost] restriction would prevent it from running.
But the "BookClass" method runs instead? I wouldn't think the routing would be correct for that one.
And I'm not sure about this one, but doesn't "asp-action" also require "asp-controller"?
Derek Vha
10,452 PointsHi Steven,
I didn't think asp-controller was needed but you may be right. Once thing I have since discovered is:
It was the line:
<a asp-action="BookClassConfirmed">Book this Class</a> |
Causing issues. Apparently the Anchor tag can not submit POST requests (unless you introduce JavaScript). I think you sort of mentioned this in your post.
I have replaced this line with :
<button>Book Class</button>
<input asp-for="@item" type="hidden"/>
And that seems to hit my POST method now. Although the object passed in is NULL for some reason so thats my next battle!
Thanks