I've been trying to learn ASP.NET Core Razor Pages with MVC and I am struggling with getting the submit button to do anything.
Here is my .cshtml code:
#page
#model MyClientBuddy.Pages.Index1Model
<form name="AddNewClient" method="post">
<tr>
<td></td>
<td><input type="text" name="firstNameTextBox" placeholder="First Name" /></td>
<input type="submit" class="btn btn-primary" asp-controller="Client" asp-action="AddNewClient" name="saveButton" value="Save">
</td>
</tr>
</form>
I made a controller class named "ClientController.cs" and put it in the "Controllers" folder.
This is what the class looks like:
using Microsoft.AspNetCore.Mvc;
namespace MyClientBuddy.Controllers
{
public class ClientController : Controller
{
[HttpPost]
public ActionResult AddNewClient(string submitButton)
{
//Do stuff...
return RedirectToAction("Clients");
}
}
}
I think the submit button is not properly linking the controller with the button and the action I want played never executes. Any idea on how to fix this? Thanks!
You need to make sure you have added routing of mvc in Program.cs.Without configuring the routing,it will not go to the controller:
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
...
app.MapRazorPages();
app.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
app.Run();
Related
Using the NET 6 core application with Pages.
Right out of the box the project has the following "code behind"
public class IndexModel : PageModel
{
private readonly ILogger<IndexModel> _logger;
public IndexModel(ILogger<IndexModel> logger)
{
_logger = logger;
}
public void OnGet()
{
}
// This is this the new code
public void MyCustomMethod()
{
var debug = "Stop Here debug break point";
}
}
The front end has the following:
#page
#model IndexModel
#{
ViewData["Title"] = "Home page";
}
<div class="text-center">
<form action="MyCustomMethod" method="get">
<input type="submit" />
</form>
</div>
Unable to GET or POST to the custom method (MyCustomMethod) in the NET 6 CORE using PAGES.
It could be a dumb question by I tried to google for the past 2 hours and can not find anything related to what I am doing. Please help.
Trying to use a simple form to get or post to the "code behind". When page load I do see a debug going into OnGet() method which it should do but clicking on a button in a form it never makes it into MyCustomMethod().
Thank you.
Did the following change to a code:
[HttpPost] // Second run added this because it was still not working
public void OnPostMyCustomMethod()
{
var debug = "Stop Here debug break point";
}
Front page
<form action="MyCustomMethod" method="post">
<input type="submit" />
</form>
Still unable access:
Debug Run
Razor Pages includes a feature called "named handler methods". This feature enables you to specify multiple methods that can be executed for a single verb.
If you have set the OnPostMyCustomMethod or MyCustomMethod in the backend codes, you should use this url "https://localhost:7086/?handler=MyCustomMethod" to access it.
More details, you could refer to below example:
<form asp-page-handler="MyCustomMethod" method="post">
<input type="submit" />
</form>
I need to remove an item in Cart with razor page. For this i used a form with asp-page-handler.
Cart.cshtml :
<td class="text-center">
<form asp-page-handler="Remove" method="post">
<input type="hidden" name="id" value="#line.Product.Id" />
<input type="hidden" name="returnUrl" value="#Model.ReturnUrl" />
<button type="submit" class="btn btn-sm btn-danger">
Remove
</button>
</form>
</td>
And my Cart.html.cs has a OnPostRemove method like this:
public IActionResult OnPostRemove(int id, string returnUrl)
{
Cart.RemoveLine(Cart.Lines.First(cl =>
cl.Product.Id == id).Product);
return RedirectToPage(new { returnUrl = returnUrl });
}
When i cliked remove button i got a 400 Error and my OnPostRemove method doesn't trigger.
Update
I included tag helper in my _ViewImports.cshtml and issue resolved.
#addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
Put the page handler inside the submit button tags.
<form method="post">
...
<button type="submit" asp-page-handler="Remove">
Remove
</button>
</form>
The code snippet that you shared seems ok, which work well with testing data on my side.
When i cliked remove button i got a 400 Error and my OnPostRemove method doesn't trigger.
To troubleshoot the issue, please check the actual request with the posted data in F12 developer tool Network tab.
And please note that if the antiforgery token validation is enabled, but the request does not include a valid antiforgery token or something wrong with the antiforgery cookies, which would also cause 400 Bad Request error.
For testing purpose, you can try to skip antiforgery token validation by applying IgnoreAntiforgeryTokenAttribute on page model class, then check if the request can be handled as expected.
[IgnoreAntiforgeryToken]
public class CartModel : PageModel
{
(Using ASP.NET Core 3.1 - Razor Pages web application)
I am trying to trigger OnPost method which is in Areas >> Login >> Pages >> Index.cshtml.cs Razor Page. Somehow, it triggers OnGet method but when I try to post a form, it didn't trigger OnPost method.
Index.cshtml.cs
namespace WebApplication1.Areas.Login.Pages
{
public class IndexModel : PageModel
{
public void OnGet()
{
//triggering
}
public void OnPost()
{
//not triggering
}
}
}
Index.cshtml
#page
#model WebApplication1.Areas.Login.Pages.IndexModel
#{
}
<form method="post">
<input name="UserId" class="form-control" />
<input type="submit" value="Create" class="btn btn-primary" />
</form>
Note:
If I am not using Areas, OnGet and OnPost working fine.
I have tried below but none of them worked for me:
Tried https://www.learnrazorpages.com/advanced/areas
How can Add Area in razor pages on dot net core 3.0/3.1?
I found the answer here: I have added the following code in Areas → Login → Pages
_ViewImports.cshtml:
#using WebApplication1
#namespace WebApplication1.Web.Areas.Login.Pages
#addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
I have a small problem with routing and forms on ASP.NET Core 1.0.0. I have the following actions:
[Route("delete/{id:int}")]
[HttpGet]
public async Task<IActionResult> Delete(int id)
{
Post post = await _postsRepository.GetPost(id);
return View(new DeletePostViewModel
{
PostId=post.Id,
Title=post.Title
});
}
[Route("delete"),HttpPost,ValidateAntiForgeryToken]
public async Task<IActionResult> Delete([FromForm]DeletePostViewModel vm,string option)
{
if (option == "Delete")
await _postsRepository.DeletePost(vm.PostId);
return RedirectToAction("Index");
}
And in my view I have the following:
<form asp-action="Delete" asp-controller="AdminPosts" asp-area="Admin" method="post" role="form">
<div class="form-group">
<input type="hidden" asp-for="PostId"/>
<label asp-for="Title"></label>
<input type="text" asp-for="Title" class="form-control" readonly="readonly"/>
</div>
<p>
<input type="submit" name="option" value="Delete" class="btn btn-danger" />
<input type="submit" name="option" value="Cancel" class="btn btn-default" />
</p>
</form>
But it does not resolve the route correctly. The route I get for the form post has also the id, and so it does not resolve the id. I have to either add the id to the form method:
[Route("delete/{id:int}"),HttpPost,ValidateAntiForgeryToken]
public async Task<IActionResult> Delete(int id,[FromForm]DeletePostViewModel vm,string option)
or I have to remove the id explicitly in the form taghelper:
<form asp-action="Delete" asp-controller="AdminPosts" asp-area="Admin" asp-route-id="" method="post" role="form">
What might I be doing wrong here? Why is it not resolving the route correctly?
Yes, you would have to remove the id explicitly as you have already figured out. This is because id is an ambient value which is why its being used during link generation.
Regarding why this is happening:
In general (either regular or attribute routes), when routes are to be ordered, most specific routes need to come before less specific routes and also routes with larger number of segments come before routes with lesser number of segments. So in your scenario the route delete/{id:int} would be automatically ordered to come before delete. Now since the value for id is ambient, the first route's conditions are met and hence your are seeing the link generated in that way, so to fix it you would need to clear it.
I've started with asp mvc 3, with c# and razor, then. I want to use forms with security for send petitions POST.
I want to with razor render some like that
<form action="/sass/" method="post">
#using (Html.BeginForm()) {
#Html.AntiForgeryToken()
<div class="form-group">
<label>Ingresa tu Nombre</label>
<input class="form-control" name="nombre" />
</div>
<div class="form-group">
<input type="submit" value="Enviar mi duda" class="btn btn-primary btn-sm" />
</div>
}
And in C# I dont know how to validate that csrf token, is valid.
I work with C#, asp mvc3 and razor.
Please help me!
In your action method you need to add the respective attribute [ValidateAntiForgeryToken], and it validate the input for you.
You have a problem with the state of your code. There are two embedded forms: the outer one and the one produced by Html.BeginForm. However, the way to validate the token is to decorate the target action or controller with [ValidateAntiForgeryToken].
So either:
[ValidateAntiForgeryToken]
public ActionResult Index()
{
return View();
}
or to validate all methods in the controller:
[ValidateAntiForgeryToken]
public class MyController : Controller
{
}