Can't i set Session in a class file? - asp.net

Why session is null in this even if i set:
public class HelperClass
{
public AtuhenticatedUser f_IsAuthenticated(bool _bRedirect)
{
HttpContext.Current.Session["yk"] = DAO.context.GetById<AtuhenticatedUser>(1);
if (HttpContext.Current.Session["yk"] == null)
{
if (_bRedirect)
{
HttpContext.Current.Response.Redirect(ConfigurationManager.AppSettings["loginPage"] + "?msg=You have to login.");
}
return null;
}
return (AtuhenticatedUser)HttpContext.Current.Session["yk"];
}
}

Usually session is not available on application authenticate request.
Session will be available after OnAcquireRequestState call.
Here is application events call sequence
Also, note that session will be available, only if target HttpHandler implements IRequiresSessionState or IReadOnlySessionState, and AuhenticateRequest is usually called for resources like .js or .jpg.

Just throwing this out there. The proper way to reference it is:
System.Web.HttpContext.Current.Session
Or if you've referenced this assembly HttpContext.Current.Session should be good to go.

When i call the method with this code i'm getting error:
public partial class AddNews : System.Web.UI.Page
{
private AtuhenticatedUser yk = (new HelperClass()).f_IsAuthenticated(true);
protected void Page_Load(object sender, EventArgs e)
{
//
}
But when i call the method in Page_Load function it is working
public partial class AddNews : System.Web.UI.Page
{
private AtuhenticatedUser yk =new AtuhenticatedUser();
protected void Page_Load(object sender, EventArgs e)
{
yk = (new HelperClass()).f_IsAuthenticated(true);
}
I think Valera Kolupaev is right ;)

Related

Exception Handling in ASP.NET MVC 4, 5

I am using ASP.NET MVC 4
I want to trace or handle Exception globally.
1.Which is handled by user code?
2.Which is not handled by user code?
both the type
how is it possible ?
Global error handling:
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Error(object sender, EventArgs e)
{
Exception exception = Server.GetLastError();
Server.ClearError();
Response.Redirect("/Home/Error");
}
}
Or override OnException method:
public class HomeController : Controller
{
protected override void OnException(ExceptionContext filterContext)
{
Exception ex = filterContext.Exception;
filterContext.ExceptionHandled = true;
var model = new HandleErrorInfo(filterContext.Exception, "Controller","Action");
filterContext.Result = new ViewResult()
{
ViewName = "Error",
ViewData = new ViewDataDictionary(model)
};
}
}
http://www.codeguru.com/csharp/.net/net_asp/mvc/handling-errors-in-asp.net-mvc-applications.htm
Shows different ways of handling errors globally. Setting a global exception handling filter is the usual.
GlobalFilters.Filters.Add(new SpecialHandleErrorAttributeCreatedByYou());
You would derive a new Attribute from HandleErrorAttribute and put your logic in there, overriding the OnException method.
public override void OnException(ExceptionContext filterContext)
However this will not show you exceptions that are handled by other code. That is the point, they are handled so they do not continue to bubble up the stack. You would have to put code in each of those catch blocks to either do what you want.
Yes it is possible you can override. HandleErrorAttribute
And register it globally
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(YourNewHandler());
...
}

Call parent page function from user control

I have a Default.aspx page and I am using a usercontrol in it. On some condition in usercontrol.cs I have to invoke a function present in Default.aspx.cs page (i.e parent page of user control). Please help and tell me the way to do this task.
You have to cast the Page property to the actual type:
var def = this.Page as _Default;
if(def != null)
{
def.FunctionName();
}
the method must be public:
public partial class _Default : System.Web.UI.Page
{
public void FunctionName()
{
}
}
But note that this is not best-practise since you are hard-linking the UserControl with a Page. Normally one purpose of a UserControl is reusability. Not anymore here. The best way to communicate from a UserControl with it's page is using a custom event which can be handled by the page.
Mastering Page-UserControl Communication - event driven communication
Add an event to the user control:
public event EventHandler SpecialCondition;
Raise this event inside your user control when the condition is met:
private void RaiseSpecialCondition()
{
if (SpecialCondition != null) // If nobody subscribed to the event, it will be null.
SpecialCondition(this, EventArgs.Empty);
}
Then in your page containing the user control, listen for the event:
public partial class _Default : System.Web.UI.Page
{
public void Page_OnLoad(object sender, EventArgs e)
{
this.UserControl1.OnSpecialCondition += HandleSpecialCondition;
}
public void HandleSpecialCondition(object sender, EventArgs e)
{
// Your handler here.
}
}
You can change the EventArgs to something more useful to pass values around, if required.
parent.aspx.cs
public void DisplayMsg(string message)
{
if (message == "" || message == null) message = "Default Message";
Response.Write(message);
}
To Call function of parent Page from user control use the following:
UserControl.ascx.cs
this.Page.GetType().InvokeMember("DisplayMsg", System.Reflection.BindingFlags.InvokeMethod, null, this.Page, new object[] { "My Message" });
This works fine for me..
Try this
MyAspxClassName aspxobj= new MyUserControlClassName();
aspxobj.YourMethod(param);

How do I avoid calling my initialization method repeatedly in ASP.NET?

protected void Page_Load(object sender, EventArgs e) {
if (!IsPostBack) { // sadly, **never** in here }
MyInit() // Slow initialization method, that I only wan't to call one time.
}
So, if I can't tuck my MyInit() in the if, can I solve my performance/strucktur problem with use of OnNeedDataSource()?
Not really sure if this is what you mean, but to initialise something once from Page_Load, you could use a static class with a static bool to determine if it's been initialized. Given it's on Page_Load, you'll also need to guard against multiple threads - so use a double checked lock to make it threadsafe and guard against a race condition.
public static class InitMe
{
private static bool isInitialized = false;
private static object theLock = new Object();
public static void MyInit()
{
if(!isInitialized)
{
lock(theLock);
{
if(!isInitialized) // double checked lock for thread safety
{
// Perform initialization
isInitialized = true;
}
}
}
}
}
and in your Page_Load, call it via InitMe.MyInit()
Hope that helps.
Try this:
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
if (!Page.IsPostBack) { MyInit(); }
}
I assume you are in a page or user control...
HTH.

How to intercept and pre-process QueryStrings in Asp.Net

We send out registration urls to clients via email. Some of the email clients are turning the url into
url <url>
I think it may be happening when users forward the email onto themselves at which point the email client re-formats the original email (maybe)
E.g.
https://my.app.com/login.aspx?param=var
Becomes
https://my.app.com/login.aspx?param=var%20%3Chttps://my.app.com/login.aspx?param=var%3E
Which rightly produces System.Web.HttpRequestValidationException: A potentially dangerous Request.QueryString value was detected
Where in the code should I intercept these instances and santize the url so that the user is re-directed onto the original form of the url?
global.asax?
Page_Init?
HttpHandler?
Pipeline?
You can catch it in Global Application_BeginRequest or in the same event in an HttpModule.
Global
using System;
using System.Web;
namespace MassageIncomingRequestUrl
{
public class Global : HttpApplication
{
protected void Application_BeginRequest(object sender, EventArgs e)
{
var app = (HttpApplication) sender;
string path = app.Context.Request.Url.PathAndQuery;
int pos = path.IndexOf("%20%3C");
if (pos > -1)
{
path = path.Substring(0, pos);
app.Context.RewritePath(path);
}
}
}
}
Module
using System;
using System.Web;
namespace MassageIncomingRequestUrl
{
public class UrlMungeModule : IHttpModule
{
#region IHttpModule Members
public void Init(HttpApplication context)
{
context.BeginRequest += BeginRequest;
}
public void Dispose()
{
//nop
}
#endregion
private static void BeginRequest(object sender, EventArgs e)
{
var app = (HttpApplication)sender;
string path = app.Context.Request.Url.PathAndQuery;
int pos = path.IndexOf("%20%3C");
if (pos>-1)
{
path = path.Substring(0,pos);
app.Context.RewritePath(path);
}
}
}
}
This will get your request processed with the correct query string in the Request, regardless of what you see in the browser address. You may be able to take extra steps to remove the garbage from the reported url but that is mainly just aesthetics.

How to use Castle Windsor with ASP.Net web forms?

I am trying to wire up dependency injection with Windsor to standard asp.net web forms. I think I have achieved this using a HttpModule and a CustomAttribute (code shown below), although the solution seems a little clunky and was wondering if there is a better supported solution out of the box with Windsor?
There are several files all shown together here
// index.aspx.cs
public partial class IndexPage : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
Logger.Write("page loading");
}
[Inject]
public ILogger Logger { get; set; }
}
// WindsorHttpModule.cs
public class WindsorHttpModule : IHttpModule
{
private HttpApplication _application;
private IoCProvider _iocProvider;
public void Init(HttpApplication context)
{
_application = context;
_iocProvider = context as IoCProvider;
if(_iocProvider == null)
{
throw new InvalidOperationException("Application must implement IoCProvider");
}
_application.PreRequestHandlerExecute += InitiateWindsor;
}
private void InitiateWindsor(object sender, System.EventArgs e)
{
Page currentPage = _application.Context.CurrentHandler as Page;
if(currentPage != null)
{
InjectPropertiesOn(currentPage);
currentPage.InitComplete += delegate { InjectUserControls(currentPage); };
}
}
private void InjectUserControls(Control parent)
{
if(parent.Controls != null)
{
foreach (Control control in parent.Controls)
{
if(control is UserControl)
{
InjectPropertiesOn(control);
}
InjectUserControls(control);
}
}
}
private void InjectPropertiesOn(object currentPage)
{
PropertyInfo[] properties = currentPage.GetType().GetProperties();
foreach(PropertyInfo property in properties)
{
object[] attributes = property.GetCustomAttributes(typeof (InjectAttribute), false);
if(attributes != null && attributes.Length > 0)
{
object valueToInject = _iocProvider.Container.Resolve(property.PropertyType);
property.SetValue(currentPage, valueToInject, null);
}
}
}
}
// Global.asax.cs
public class Global : System.Web.HttpApplication, IoCProvider
{
private IWindsorContainer _container;
public override void Init()
{
base.Init();
InitializeIoC();
}
private void InitializeIoC()
{
_container = new WindsorContainer();
_container.AddComponent<ILogger, Logger>();
}
public IWindsorContainer Container
{
get { return _container; }
}
}
public interface IoCProvider
{
IWindsorContainer Container { get; }
}
I think you're basically on the right track - If you have not already I would suggest taking a look at Rhino Igloo, an WebForms MVC framework, Here's a good blog post on this and the source is here - Ayende (the Author of Rhino Igloo) tackles the issue of using Windsor with webforms quite well in this project/library.
I would cache the reflection info if you're going to inject the entire nested set of controls, that could end up being a bit of a performance hog I suspect.
Last of all spring.net approaches this in a more configuration-oriented way, but it might be worth taking a look at their implementation - here's a good reference blog post on this.
Here's a modified version of the OP's code that (i) caches injected properties to avoid repeated reflection calls, (ii) releases all resolved components, (iii) encapsulates container access so as not to expose implementation.
// global.asax.cs
public class Global : HttpApplication
{
private static IWindsorContainer _container;
protected void Application_Start(object sender, EventArgs e)
{
_container = new WindsorContainer();
_container.Install(FromAssembly.This());
}
internal static object Resolve(Type type)
{
return _container.Resolve(type);
}
internal static void Release(object component)
{
_container.Release(component);
}
//...
}
// WindsorHttpModule.cs
public class WindsorHttpModule : IHttpModule
{
// cache the properties to inject for each page
private static readonly ConcurrentDictionary<Type, PropertyInfo[]> InjectedProperties = new ConcurrentDictionary<Type, PropertyInfo[]>();
private HttpApplication _context;
public void Init(HttpApplication context)
{
_context = context;
_context.PreRequestHandlerExecute += InjectProperties;
_context.EndRequest += ReleaseComponents;
}
private void InjectProperties(object sender, EventArgs e)
{
var currentPage = _context.Context.CurrentHandler as Page;
if (currentPage != null)
{
InjectProperties(currentPage);
currentPage.InitComplete += delegate { InjectUserControls(currentPage); };
}
}
private void InjectUserControls(Control parent)
{
foreach (Control control in parent.Controls)
{
if (control is UserControl)
{
InjectProperties(control);
}
InjectUserControls(control);
}
}
private void InjectProperties(Control control)
{
ResolvedComponents = new List<object>();
var pageType = control.GetType();
PropertyInfo[] properties;
if (!InjectedProperties.TryGetValue(pageType, out properties))
{
properties = control.GetType().GetProperties()
.Where(p => p.GetCustomAttributes(typeof(InjectAttribute), false).Length > 0)
.ToArray();
InjectedProperties.TryAdd(pageType, properties);
}
foreach (var property in properties)
{
var component = Global.Resolve(property.PropertyType);
property.SetValue(control, component, null);
ResolvedComponents.Add(component);
}
}
private void ReleaseComponents(object sender, EventArgs e)
{
var resolvedComponents = ResolvedComponents;
if (resolvedComponents != null)
{
foreach (var component in ResolvedComponents)
{
Global.Release(component);
}
}
}
private List<object> ResolvedComponents
{
get { return (List<object>)HttpContext.Current.Items["ResolvedComponents"]; }
set { HttpContext.Current.Items["ResolvedComponents"] = value; }
}
public void Dispose()
{ }
}
I've recently started at a company where there are a lot of legacy webform apps, so this looks to be a real interesting approach, and could offer a way forward if we wanted to add DI to existing web pages, thanks.
One point I noticed is that the Injection method uses the container.Resolve to explicitly resolve components, therefore I think we may need to do a container.Release on the components when the Page Unloads.
If we have transient components and don't do this then we may face memory leakages. Not sure how components with Per Web Request lifestyles would behave (i.e. would Windsor pick them up at the end of the web request, even though we explicitly resolved them) but here too may want to play safe.
Therefore the module may need to be extended to keep track of the components that it resolves and release them so that Windsor knows when to clean up.
One thing that was missing from the accepted answers was the fact that the http module needs to be registered in the web.config file (depending on the application) before the module will actually resolve the dependencies on the code-behind pages. What you need is :
<system.webServer>
<modules>
<add name="ClassNameForHttpModuleHere" type="NamespaceForClass"/>
</modules>
</system.webServer>
Other than that the accepted solutions worked like a charm.
Reference to the Microsoft website for adding http modules: https://msdn.microsoft.com/en-us/library/ms227673.aspx
Rather than doing it like this, you could also use a type resolver directly with something like:
ILogger Logger = ResolveType.Of<ILogger>();

Resources