Using Tempdata in a class - asp.net

I made an annotation for pages that require logging in, if the user is not logged in it will be redirected to the login page. I would also like to add an error which requires tempdata to view the error. Otherwise i have to set an message and check if the user is logged in every controller.
So my question is if it's possible to set a tempdata in a non controller, if it's possible how could i achieve this?

Do you mean you made a action filter for those pages? If so, you can access tempdata in the filter context.
public void OnActionExecuting(ActionExecutingContext filterContext)
{
filterContext.Controller.TempData
...
}

Related

ASP.NET MVC Session state is lost

I have a controller and two actions in it:
public ActionResult Index()
{
this.Session.Add("Boo", "Foo");
return View();
}
public ActionResult Details()
{
Debug.WriteLine(this.Session["Boo"]);
return View();
}
Then on the Index View I have a link
<div class="form-group">
#Html.ActionLink("Details", "details")
</div>
When Index action is invoked I set session variable "Boo", then in the Index View, I click on the Details link and when I get to Details action, Session ID is different from what it was in the Index action, and obviously this.Session["Boo"] is null.
Any ideas why is it happening?
Thanks!
This happens when cookies are disabled in a browser. Therefore, the session does not preserve the state.
Even with browsers that do support cookies, some users prefer to turn off cookie support. If your application needs to be responsive to browsers that don't support cookies, you cannot use ASP session management.
In this case, you must write your own mechanism to pass information from page to page in your application. There are two general ways to do this:
Add parameters to a URL's query string.
Add hidden values to a form.
For more information see documentation: Using Cookies to Maintain Sessions in ASP

How to get custom user property in Razor ASP.NET without any ViewModels?

I created my new custom property for User in ASP.NET project ("DarkTheme").
I have a problem (see below). I can access User.Identity.Name without any ViewModels. I can access User.Identity.IsInRole() and so on. But I cannot access my new property ("DarkTheme"). I do not want to use viewmodels (I would have to rewrite the whole application). Is there a way to go to the place where ASP.NET makes User.Identity.Name accessible without any ViewModels and add "DarkTheme" property?
I didn't find the answer to this problem, but I have a workaround.
I used User.IsInRole("DarkTheme") attribute to pass the value to the view (and load different css files depending on the value). It is the only role that user can assign to himself without manager permission.
You could use OnActionExecuted method in your controller in combination with dynamic ViewBag
protected override void OnActionExecuted(ActionExecutedContext filterContext)
{
if (Request.IsAjaxRequest() || filterContext.IsChildAction) return; // you don't need styling for ajax requests which return json
base.OnActionExecuted(filterContext);
YourUser user = ... // get user from db/claims or get theme from cookies etc.;
ViewBag.DarkTheme = user.DarkTheme;
}
and in view it will be invoked simply by #ViewBag.DarkTheme, no namespace needed

Detect what Attributes are set on a controllers action during Application_AuthenticateRequest

I get a call to Application_AuthenticateRequest which I use to perform some authentication logic. Something similar to:
protected void Application_AuthenticateRequest(Object sender, EventArgs e)
{
if (System.Web.HttpContext.Current.Request.IsAuthenticated)
{
....
}
}
That works generally fine, however in some cases my controller actions have the AllowAnonymous attribute attached, and I do not want the code to execute. The is no problem if the user is not logged in, however, if the user is logged in and they attempt to access one of these views, I run into an issue.
What I'm wondering is, if there is a way I can detect what attributes are set on my action in the Application_AuthenticateRequest call. Or if I could even detect if the current page requres authentication?
So far I haven't been able to figure this out, but it seems like it should be fairly simple. I'm wondering if someone could point out something that I'm missing?
This question is little old. But I came across to find an answer. I found a solution by using System.Web.HttpContext.Current.SkipAuthorization
This returns true if the action has [AllowAnonymous] attribute,
Else this returns false if the action has [Authorize] attribute.

Register before entering the main site

When someone visits my site and if there isn't any admin registered they should be redirected to that Adminregistration page.
Now this should ONLY happen when there isn't any admin registered whatsoever. So it should only happen when the database is fresh and empty without data.
I know I can put a check with a validationattribute on all controllers. But I find that a bit of a hack and well... The check should be completely removed when there is 1 registered anyway.
So is there another way to accomplish this?
If you have a base controller that all your controllers inherit from, you could put the "validationattribute" you mention on the base controller to trigger the validation on every request, if that is what you want.
Edit
You could store a global variable in web.config called say AdminIsRegistered that is set to false when the application is first shipped. Then you change that value programatically when the first admin registers like this and set it to true. Your custom attribute set on the base controller could then simply check that value on every request, as long as it is set to false, the attribute redirect the user to the registration action, otherwise it does nothing.
The best way to do this is with a global filter. You register it once in your application, and every action that executes will hit the filter first. All you have to do is add it to the global filter collection on Application_Start:
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
GlobalFilters.Filters.Add(new AdminRequiredAttribute());
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
}

ActionFilter does not execute with cached output

I am using the OutputCache attribute to cache my home page content
[OutputCache(CacheProfile = "Default")]
public ActionResult Index()
{
.....
}
I also have a custom global attribute set-up that checks each request for a valid browser type
GlobalFilters.Filters.Add(new BadBrowserAttribute());
The OnActionExecuting fires as needed during the first request, but not again until the cache expires.
I had thought the Order value of the attributes may help but it doesn't seem to have made any difference.
Is it possible to get my custom attribute to fire every time for cached content?
It's impossible for your action to fire everytime. When you use caching (as in your code), on subsequent request results will be returned from cache, so action won't be executed.
A workoround might be to implement custom caching inside your action filter. Something like this

Resources