Why OnPost is not getting hit without "#addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers" in ASP.NET Core version 5.0 - httprequest

I'm using ASP.NET CORE version 5.0, and I'm using razor pages for my web UI. I was having a problem hitting a simple OnPost method with the following structure in HTML:
#page
#model EmptyOne.Web.Pages.SaysHelloModel
#{
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Search</title>
</head>
<body>
<p>Enter the name you wanna say hello two ;)</p>
<form method="post">
Search term:
<input name="nameToHello" />
<input type="submit" />
</form>
#* some logic to say hello if model is not null... *#
</body>
</html>
And this is my page model class:
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
namespace EmptyOne.Web.Pages
{
public class SaysHelloModel : PageModel
{
public string guysName { get; set; }
public void OnGet()
{
}
public IActionResult OnPost(string nameToHello)
{
guysName = nameToHello;
return Page();
}
}
}
It returns an HTTP 400 status core and a blank page when I try to hit it, but for some reason, when I add this helper:
#addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
It works fine!
The final and working view(i didn't change anything in the page model class):
#page
#model EmptyOne.Web.Pages.SaysHelloModel
#{
}
#addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Search</title>
</head>
<body>
<p>Enter the name you wanna say hello two ;)</p>
<form method="post">
Search term:
<input name="nameToHello" />
<input type="submit" />
</form>
#* some logic to say hello if model is not null... *#
</body>
</html>
So can anyone explain to me why that is? I looked up an ASP.NET Core version 5.0 code example and saw this helper. Am I using this helper in any way? What does it have to do with sending an HTTP post request to my page handler?

Razor Pages includes an anti-CSRF mechanism, known as request verification, by default. It relies on a token that is applied to a hidden form field being sent with each POST request. The hidden form field is generated automatically by the form tag helper. If you omit the token value from your post, for example by disabling the form tag helper, the framework returns a 400 Bad Request.

Related

Razor class library and html helpers problem

I create a small admin tool and I decided to convert it to a Razor class library so that I will be able to use it in other applications as well. I created the Razor Class Library project and I added all the razor pages that I had in my main project and I tried to test the new project. The problem was that the framework for some reason did not recognize the html helpers so I created a new clean project and try to find out what is wrong and the result was that the application did not fire the post action of the razor page and the asp-for property was not using properly the property value. I used the following code in order to test the Razor Class Library.
Page1.cshtml.cs
public class Page1Model : PageModel
{
[BindProperty]
public Input MyInput { get; set; }
public class Input
{
public string Name { get; set; }
}
public void OnGet()
{
}
public void OnPost()
{
}
}
Page1.cshtml
#page
#model WebApplication1.MyFeature.Pages.Page1Model
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Page1</title>
</head>
<body>
<form method="post">
<input asp-for="MyInput.Name" /><br />
<input type="submit" />
</form>
</body>
</html>
The generated html was the following
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Page1</title>
</head>
<body>
<form method="post">
<input asp-for="MyInput.Name" /><br />
<input type="submit" />
</form>
</body>
</html>
As you can see the input for MyInput.Name appears as I typed it the Page1.cshtml file. The right output shoud be the following:
<input type="text" id="MyInput_Name" name="MyInput.Name" value="" /><br />
Do I have to do something in order to make the html helpers work and the OnPost action to be called when a post request occurs?
I found the solution to the problem and I decided to share it with you just in case someone else has the same problem.
In order to make it work I had to add the file _ViewImports.cshtml in the pages folder of the Razor Class Library and add the following line:
#addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

Asp.net page methods not getting called

I have a simple example of page method.but its not getting called.the breakpoint at GetDate() function never get hit and always it shows alert as 'Failure'.
aspx page is :
<%# Page Language="C#" AutoEventWireup="true" CodeFile="Default13.aspx.cs" Inherits="Default13" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js" type="text/javascript"></script>
<script type="text/javascript" language="javascript" >
function btnTest_onclick() {
PageMethods.GetDate(Success, Failure);
}
function Success(data) {
alert("success");
alert(data);
}
function Failure(data) {
alert("failure");
alert(data.toSource());
}
</script>
</head>
<body >
<form id="form1" runat="server" method="post">
<div>
<asp:ScriptManager ID="ScriptManager1" runat="server" EnablePageMethods="true" ScriptMode="Debug" >
</asp:ScriptManager>
<%--<input type="button" id="btnSave" value="Save" onclick="btnTest_onclick" />--%>
<asp:Button id="btnSave" runat="server" Text="Save" OnClientClick="btnTest_onclick()"/>
</div>
</form>
</body>
</html>
and the aspx.cs page is:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.Services;
public partial class Default13 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
[System.Web.Services.WebMethod]
[System.Web.Script.Services.ScriptMethod]
public static string GetDate()
{
return "str";
}
}
any suggestions?
Thanks in Advance,
I think issue is because your button is server side control, will suggest you to call PageMethod from html button instead.
Still If you require to do so,Please try following code.
<asp:Button id="btnSave" runat="server" Text="Save" OnClientClick="btnTest_onclick(); return false;"/>

Html.RenderPartial Works but Html.RenderAction not working (is blank) and no errors or exceptions

Here is what i am trying
Layout
<!DOCTYPE html>
<html lang="en">
<head>
<title>WebApp Name</title>
<meta charset="utf-8" />
</head>
<body>
<div id="menuContainer">
#{Html.RenderPartial("~/Views/CustomPartials/_MainMenuPartial.cshtml");} #*Works*#
#*#{Html.RenderAction("GetMenuStructure", "Custom");}*# #*Not working*#
</div>
<div>
#RenderBody()
</div>
</body>
</html>
Controller and Action method
namespace Webappl.Controllers
{
[Authorize]
public class CustomController : Controller
{
[AllowAnonymous]
[ChildActionOnly]
public ActionResult GetMenuStructure()
{
return PartialView("~/Views/CustomPartials/_MainMenuPartial.cshtml");
}
}
}
_MainMenuPartial.cshtml
<ul id="ul_MainMenuStructure">
<li>Guest Pg1</li>
<li>Guest Pg2</li>
<li>Guest Pg3</li>
</ul>
The problem is
#{Html.RenderPartial("~/Views/CustomPartials/_MainMenuPartial.cshtml");}
Renders the contents of _MainMenuPartial.cshtml into the layout perfectly.
While
#{Html.RenderAction("GetMenuStructure", "Custom");}
Does nothing. No errors. No exceptions. Just blank. If i place a break-point at
return PartialView("~/Views/CustomPartials/_MainMenuPartial.cshtml");
The break-point is getting hit. I press F5 and it goes forward without any error/exceptions but menu structure does not get rendered in the layout. All I have is a blank
<div id="menuContainer">
</div>
in the final rendered page when I view it in the browser.
I need to do it through the action method for certain custom logic to be executed. Thats why a render partial is not sufficient.
I was not able to find similar behavior reported any where including stackoverflow. It could be bad binging/googling skills.
Some help will be so greatly appreciated. Banging my head on it for 3 days now.
I simply changed
#Html.RenderAction("X", "Y")
To
#Html.Action("X", "Y")

Authenticated users being redirected to login

My application (MVC4/C#) uses the SimpleMembershipProvider and generally works fine. However, I have a problem that I cannot resolve after spending many hours researching and testing.
If I leave my application for a period of time (say 30 minutes) then select a menu item, the page renders (sidebar/header/footer), but the #RenderBody section redirects to the ~/Account/Login action.
If I then ignore the login and click on any controller action link (from the menu) then it loads as expected. It appears that the razor layout view correctly thinks I am authenticated, but the controller doesn't think I am authorized. I have a base class for most of my controllers that I inherit from that has the [Authorize] attribute.
If I logout, only the RenderBody section renders as expected, for ~/Account/Login action.
From web.config
<system.web>
<roleManager enabled="true" />
<authentication mode="Forms">
<forms loginUrl="~/Account/Login" timeout="2880" />
</authentication>
Base controller
[Authorize]
public abstract class AuthorizeBaseController : Controller
{
}
Controllers
public class SiteController : AuthorizeBaseController
{
private SiteContext db = new SiteContext();
public ActionResult Index()
{
return View(db.Sites.ToList());
}
:
_Layout.cshtml
:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>#ViewBag.Title</title>
<link href="~/favicon.ico" rel="shortcut icon" type="image/x-icon" />
<meta name="viewport" content="width=device-width" />
#Styles.Render("~/Content/css")
#Scripts.Render("~/bundles/modernizr")
#Styles.Render("~/Content/menubar.css")
</head>
<body>
#if (Request.IsAuthenticated)
{
<div id="header">
:
</div>
<div id="sidebar">
:
</div> <!-- sidebar -->
}
<div id="body">
#RenderBody()
</div>
#if (Request.IsAuthenticated)
{
<footer>
:
</footer>
}
#Scripts.Render("~/bundles/jquery")
#RenderSection("scripts", required: false)
</body>
</html>
It is because
[Authorize]
AuthorizeAttribute is MVC in built Attribute . make your own customize Attribute . You can have result as expect you .
Right now you can remove this Authorize Attribute from your every Controller and Action then your problem will solved .
The problem was caused by the SimpleMembershipProvider. In short, sometimes my Authorise filter was being called before InitializeSimpleMembershipAttribute().
I got my solution from this post which refers to a more detailed explanation on Scott Allen's blog

Use controller result from other mvc project within solution

I've got a new solution that contains several project 'groups'. Each group contains a Cloud Project, a Web Role Project and a Test Project. All Web Role Projects are MVC4.
One of the Web Roles is the entry point for the visitor. Parts of what the visitor will see, should come from the other Web Roles from within the solution. I cannot get it working and after spending several hours googling, I still cannot solve it. Maybe anyone can be helpful on this issue.
For example, I need to fill the header content with data that I can get from one of the other Web Roles. Let's call that controller HeaderController. The controller in the main project (HomeController) looks like this:
public class HomeController : Controller
{
public ActionResult Index()
{
ViewBag.Message = "Modify this template to jump-start your ASP.NET MVC application.";
//var headerController = new Generic.HeaderFooterContainer.Controllers.HeaderController();
//var foo = headerController.Index().ExecuteResult();
//ViewBag.Header = headerController.;
return View();
}
In the comments are some things I've tried to debug some things.
Here's the page layout of the main project. The body is still empty, as this problem is just about the page header which could be placed as html from the ViewBag or ViewData or even with an own #section.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
<head>
<meta charset="utf-8" />
<title>#ViewBag.Title</title>
<link href="~/favicon.ico" rel="shortcut icon" type="image/x-icon" />
<meta name="viewport" content="width=device-width" />
#Styles.Render("~/Content/css")
#Scripts.Render("~/bundles/modernizr")
</head>
<body>
<div class="headerHolder">
<div class="innertube">
<div id="header">
#ViewBag.Header
</div>
</div>
</div>
<div class="contentHolder">
<div class="innertube">
<div id="content">
#RenderBody()
</div>
</div>
</div>
<div class="footerHolder">
<div class="innertube">
<div id="footer">
</div>
</div>
</div>
#Scripts.Render("~/bundles/jquery")
#Scripts.Render("~/bundles/bms")
#RenderSection("scripts", required: false)
</body>
</html>
The problem I face is that I just can't find out how I should make this work. How do I get the data in the header? A few things I've noticed are:
If I run the HeaderFooterContainer project in its dedicated solution, it works alright (I can get /Header and get the expected response displayed in the browser window)
If I run the Main project, I can see the home page, but if I ask for /Header, it can find the controller, but not the view. It's probably looking for the view in the main project although it is located in the HeaderFooterContainer project.