Authenticated users being redirected to login - asp.net-mvc-4

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

Related

Redirecting in Asp.Net Core Middleware

I'm attempting to learn how to perform redirects/rewrites in a Asp.NET Core app and I am following this article: Back to Basics: Rewriting a URL in ASP.NET Core. However, when I attempt the example for "Re-writing a URL" section, I only see the main "/Index" page and not the "/TargetPage".
I can browse to the "/TargetPage" manually and it will render but it is not done automatically. I'm attempting this method of rewrite/redirect based upon "flags" that will be set in the "appSettings.json" file of the program.
This is the code for the "Startup.cs" file:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseStaticFiles();
app.UseRouting();
app.Use(async (context, next) =>
{
string url = context.Request.Path.Value;
if (!url.Contains("/TargetPage") && AppSettings.SendUserToTargetPage == true)
{
context.Request.Path = "/TargetPage";
}
await next();
});
app.UseEndpoints(endpoints =>
{
endpoints.MapBlazorHub();
endpoints.MapFallbackToPage("/_Host");
});
}
This is the code for the "_Host.cshtml" file:
#page "/"
#namespace MyTestApp.Pages
#addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
#{
Layout = null;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>My Test Redirect</title>
<base href="~/" />
<link href="~/Styles/reset.css" rel="stylesheet" />
<link href="~/Styles/bootstrap.min.css" rel="stylesheet" />
<link href="~/Styles/site.css" rel="stylesheet" />
</head>
<body>
<component type="typeof(App)" render-mode="Server" />
<script src="_framework/blazor.server.js"></script>
</body>
</html>
This is the code for the "/Index" page:
#page "/"
<h1>Hello, world!</h1>
Welcome to your new app.
This is the code for the "/TargetPage":
#page "/TargetPage"
<h3>The page I'm trying to get to.</h3>
Once the app is started, I arrive at the root "/" page (localhost:#some_port_number) where "Hello, world!" is displayed and the URL never arrives "/TargetPage" as I expect it to.
Is there something specific I am missing or have misconfigured? This example is being done in .NET 5 at the moment (if that has any bearing at all).
Regards.
Middleware is for Razor Pages / MVC applications. Blazor has no concept of an HTTP Request pipeline, therefore there is no middleware.
In the case of Blazor WASM, the app is loaded into the browser and code executes in the browser.
In your case of Blazor Server, the app is run on the server, and rendered updates are pushed over a SignalR connection.
See: Custom URL rewrite rule in Blazor ASP.Net Core (server-side) not triggering when using navlink

How to embed tableau into asp.net core blazor?

I am trying to embed tableau object into razor page in blazor application but its not working it shows blank page and it will not log any error in browser console.
Below is the razor page.
Tableau.razor
#page "/tableau"
<h3>Tableau Example</h3>
<body>
<div class='tableauPlaceholder' style='width: 1700px; height: 950px;'>
<object class='tableauViz' width='1700' height='950' style='display:none;'>
<param name='host_url' value='https%3A%2F%2Ftableau.xxxxxx.com%2F' />
<param name='embed_code_version' value='3' />
<param name='site_root' value='/t/ITRD' />
<param name='name' value='AgileDEStrainingStatus/Agilemind-setTrainings' />
<param name='tabs' value='yes' /><param name='toolbar' value='yes' />
<param name='showAppBanner' value='false' />
<param name='filter' value='iframeSizedToWindow=true' /></object></div>
</body>
#code {
}
_host.cshtml
#page "/"
#namespace BlazorApplication.Pages
#addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>BlazorApplication</title>
<base href="~/" />
<link rel="stylesheet" href="css/bootstrap/bootstrap.min.css" />
<link href="css/site.css" rel="stylesheet" />
</head>
<body>
<app>
#(await Html.RenderComponentAsync<App>(RenderMode.ServerPrerendered))
</app>
<script src="_framework/blazor.server.js"></script>
<script type='text/javascript' src='https://tableau.xxxxxx.com/javascripts/api/viz_v1.js'></script>
</body>
</html>
What I am doing wrong?
Thanks
I can't replicate your exact sample as the URL for your data is obviously private, but I created a Tableau sample at https://github.com/conficient/TableauSample which uses the basic example from the Tableau website
I used Server-side Blazor as per your example and was able to load the sample. What I think you're missing in your code is that there is no initiation of the Tableau library? In the Tableau sample they invoke the setup function:
<body onload="initViz();">
You can't do this in Blazor since embedded JS isn't permitted but you can use JavaScript interop
I created a basic interop file to do this:
window.initViz = function (containerDiv, url) {
// containerDiv: element to update - use #ref in Blazor to get this
console.log("initViz called for " + url);
var options = {
hideTabs: true,
onFirstInteractive: function () {
console.log("Run this code when the viz has finished loading.");
}
};
console.log("initViz calling .Viz()");
var viz = new tableau.Viz(containerDiv, url, options);
}
I also changed the sample by passing an ElementReference rather than an id - if you're going to build a component in future this is good practice since you don't need to name the elements and can have multiple instances on a page.
I then amended the Index.razor page to invoke the initViz function in OnAfterRenderAsync.

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

PartialView getting data only for one View

Hey guys i'm using asp mvc4 for building a site,im having trouble in Views
First of all i have my _Layout View calling a partialView for header and my partial View is getting data from a model in to fill some data in the header,
It's working by the way just in the Main (index) view but moving to another views just call the Partial view without getting data from database.
Hope i explained Well :D
_layout View
#model MvcApplication1.Models.SchoolInfo
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="">
<meta name="author" content="">
<title>#Html.DisplayFor(model => model.SiteName)</title>
<!-- Bootstrap Core CSS -->
<link href="~/Content/Template/css/bootstrap.min.css" rel="stylesheet">
<!-- Custom CSS -->
<link href="~/Content/Template/css/business-casual.css" rel="stylesheet">
<!-- Fonts -->
<link href="http://fonts.googleapis.com/css?family=Open+Sans:300italic,400italic,600italic,700italic,800italic,400,300,600,700,800" rel="stylesheet" type="text/css">
<link href="http://fonts.googleapis.com/css?family=Josefin+Slab:100,300,400,600,700,100italic,300italic,400italic,600italic,700italic" rel="stylesheet" type="text/css">
<!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
<script src="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script>
<![endif]-->
<body>
<header>
<section id="login">
#Html.Partial("_LoginPartial")
#if (Request.IsAuthenticated)
{
#Html.Partial("_SiteHeaderPartial")
}
</section>
</header>
#RenderBody()
#if (Request.IsAuthenticated){
<footer>
<div class="container">
<div class="row">
<div class="col-lg-12 text-center">
<p>Copyright © Your Website footer</p>
</div>
</div>
</div>
</footer>
}
<!-- jQuery -->
<script src="~/Scripts/Template/js/jquery.js"></script>
<!-- Bootstrap Core JavaScript -->
<script src="~/Scripts/Template/js/bootstrap.min.js"></script>
<!-- Script to Activate the Carousel -->
<script>
$('.carousel').carousel({
interval: 5000 //changes the speed
})
</script>
_SiteHeaderPartial
#model MvcApplication1.Models.SchoolInfo
<div class="brand">#Html.DisplayFor(model => model.SchoolName)</div>
<div class="address-bar">Country | Address : #Html.DisplayFor(model => model.SchoolAddress) | 011 #Html.DisplayFor(model => model.SchoolPhone)
Index and About views are the same (empty).
If your not seeing the details in the About.cshtml view, its because you have not passed a SchoolInfo model to that view (or the model is not populated with the data). However a layout should not include a model declaration (unless its a base model from which all views that use that layout derive).
Remove #model MvcApplication1.Models.SchoolInfo from the layout and instead of #Html.Partial("_SiteHeaderPartial"), use
#Html.Action("SiteHeader", "yourControllerName")
where SiteHeader() is a a controller method that gets your data and returns a partial view, for example
[ChildOnlyAction]
public PartialViewResult SiteHeader()
{
SchoolInfo model = ... // populate your model
return PartialView("_SiteHeaderPartial", model);
}
Sife note: You also need to remove <title>#Html.DisplayFor(model => model.SiteName)</title> or replace it with (say) <title>#ViewBag.Title</title> and in each view, pass the value to the partial using #{ ViewVag.Title = someValue; }

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.