I have an ASP.NET webform where I initialize an array with a list of controls on the page like this
FileUpload[4] = new FileUpload[4];
public myclass()
{
fileUpload[0] = FileUpload1;
fileUpload[0] = FileUpload2;
...etc
}
I then use these in the page load and they are all null. This seems a strange behavior to me. Can someone elaborate and explain? I can understand that they are null in the constructor but why should they be null when used in the page load.
They are null because the controls haven't been created yet.
Take a look at the ASP.NET Page Life Cycle Overview and the Init event.
If you want to add controls "manually", you need to do this in OnInit() so they can be given state from the LoadViewState() call that will happen just after OnInit().
If you don't know how many controls you need to add, because it's dynamic somehow, you can override LoadViewState and SaveViewState. See this example(written without Visual Studio):
public class MyPage : Page
{
class State
{
numberOfControls int
otherState object
}
override void LoadViewState(savedState object)
{
var myState = (State)savedState;
SetupMyControls(myState.numberOfControls);
base.LoadViewState(myState.otherState);
}
override object SaveViewState()
{
return new State
{
numberOfControls = GetNumberOfMyControls(),
otherState = base.SaveViewState()
};
}
}
Related
Say there is a TextBox on an ASP.NET page
<asp:TextBox id="DateTextBox" runat="server" />
with some value set in the code-behind.
How to access that value from another class of C# code-file through HttpContext or any other way?
You can access a property in you page via HttpContext even from a static method.
in your page:
public string DateTextBoxText
{
get{ return this.DateTextBox.Text; }
set{ this.DateTextBox.Text = value; }
}
somewhere else(even in a different dll):
public class Data
{
public static string GetData()
{
TypeOfYourPage page = HttpContext.Current.Handler as TypeOfYourPage;
if (page != null)
{
return page.DateTextBoxText;
//btw, what a strange method!
}
return null;
}
}
Note that this works only if it's called from within a lifecycle of this page.
It's normally better to use ViewState or Session to maintain variables across postback. Or just use the property above directly when you have a reference to this page.
You can create a public property within the control that returns a reference to the textbox.
You can then use this property to reference the textbox.
OR
You can store in into session and then access it in your entire application.
Store it in the HttpContext Session http://www.codeproject.com/Articles/32545/Exploring-Session-in-ASP-Net
//Storing UserName in Session
Session["DateTextBox"] = DateTextBox.Text;
Now, let's see how we can retrieve values from session:
//Check weather session variable null or not
if (Session["DateTextBox"] != null)
{
// use it...
}
You could place the value in the Session during the post back. Then access it from the Session in the other class. So in your form load event write this:
Session["MyValue"] = DateTextBox.Text
and then in the other class write this:
var val = HttpContext.Current.Session["MyValue"];
NET Experts,
I got an ASP.NET MVP (Model View Presenter) application, where I am using GenMaster.Master (Master Page), Metadata.aspx (Start Page), Global.asax etc.
I am accessing the Session["EncryptedQuery"] in both GenMaster.Master (Master Page) and Metadata.aspx (Start Page).
Our Session declaration convention is to use property as follows:
public string EncryptedQuery
{
get
{
object SessionObject = Session["EncryptedQuery"];
return (SessionObject == null) ? String.Empty : (string)SessionObject;
}
set
{
Session["EncryptedQuery"] = value;
}
}
Now, where should I declare this Session property to access it in Master as well as all the content pages? And I do not want to assign/retrive to/from Session["EncryptedQuery"] direcly.
Thanks
A MasterPage is implemented as a Child Control of your Page. You should be able to access it using Page.Session from the MasterPage.
I just noticed you may have been asking is where to assign the property, rather than where to declare it. So, if you're asking what is the best practice as far as where to initialize Session data, then the answer is going to be the PostAcquireRequestState event of the HttpApplication class. You can declare this in either your Global.asax, or wire it up with a custom HTTP module.
This sort of strategy works well and allows for session data access from anywhere in the site in a strongly typed manner.
public static class SessionData
{
private const string ENCRPYTED_QUERY = "ENCRPYTED_QUERY";
public static string EncrpytedQuery
{
get
{
if (HttpContext.Current.Session != null)
return HttpContext.Current.Session[ENCRPYTED_QUERY] as string;
return null;
}
set
{
HttpContext.Current.Session[ENCRPYTED_QUERY] = value;
}
}
//add more down here...
}
I am trying to make a validator that will make sure that at least 2 items are selected. The validator works correctly on the server side but the client side code never gets executed.
Here is the code:
Sys.Mvc.ValidatorRegistry.validators["country"] = function (rule) {
var min = rule.ValidationParameters["min"];
return function (value, context) {
if (value >= min) return true;
return rule.ErrorMessage;
};
};
And here is the validator code:
public class CountryValidator : DataAnnotationsModelValidator<CustomValidations.CountryAttribute>
{
private int _minimum;
private string _message;
public CountryValidator(ModelMetadata metadata, ControllerContext context, CustomValidations.CountryAttribute attribute) : base(metadata,context,attribute)
{
_minimum = attribute.Minimum;
_message = attribute.ErrorMessage;
}
public override IEnumerable<ModelClientValidationRule> GetClientValidationRules()
{
var rule = new ModelClientValidationRule()
{
ErrorMessage = _message,
ValidationType = "country"
};
rule.ValidationParameters.Add("min", _minimum);
return new[] { rule };
}
}
I have even registered the validation adapter in global.asax file:
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RegisterRoutes(RouteTable.Routes);
DataAnnotationsModelValidatorProvider.RegisterAdapter(typeof(AgeAttribute), typeof(AgeValidator));
DataAnnotationsModelValidatorProvider.RegisterAdapter(typeof(CountryAttribute),typeof(CountryValidator));
}
I am thinking that the validator only works with the elements that have a value property like textboxes etc.
UPDATE 1:
EnableClientValidation is invoked correctly and all the required JS files are included in the project. It seems like I need to attach the onblur to the context. I will try that and post the results.
<% =Html.EnableClientValidation(); %> needs to be in your view somewhere. Also make sure you reference MicrosoftAjax.js and MicrosoftMvcValidation.js in the same view (before your js function).
Either your missing MicrosoftMvcAjax.js or you need to implement your custom validation in jQuery as described on Mr. Haack's website http://haacked.com/archive/2009/11/19/aspnetmvc2-custom-validation.aspx.
I think it is because the default validation is invoked on the onblur event of the input textbox. And for a listbox this event was not being thrown.
I need the following functionality in my method: if the method is called before OnLoad event of ASP.NET life cycle throw an exception else continue execution of the method.
I was thinking of something like this:
if (Page.LifeCycleState < LifeCycleState.OnLoad) {
throw new InvalidPageStateException();
}
Is it possible to retrieve the state of ASP.NET page life cycle?
One approach would be to use a Basepage that you always use in your site. This would contain a variable called PageLoadComplete, which you would set at the end of your PageLoad event. Then you could check the state of this variable from within your method.
public abstract class BasePage : System.Web.UI.Page
{
public bool PageLoadComplete { get; private set; }
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
PageLoadComplete = true;
}
}
If you want to access the variable from code external to your page such as a UserControl, you would have to make it public and cast your page as BasePage.
public partial class MyUserControl : System.Web.UI.UserControl
{
protected void Page_Load(object sender, EventArgs e)
{
BasePage basePage = this.Page as BasePage;
if (basePage != null && !basePage.PageLoadComplete)
{
throw new InvalidPageStateException();
}
}
}
There is property in a realization of System.Web.UI.Control class(realization):
internal ControlState ControlState {
get { return _controlState; }
set { _controlState = value; }
}
Where ControlState is enum that contains members such as: Initialized, ViewStateLoaded, Loaded etc. here declaration
But as you can see this property is internal. So only way to get control state is proposed by Daniel Dyson.
You maybe able to find what you are looking for, by looking at the CurrentHandler and PreviousHandler properties of the current HttpContext.
if the method is called before OnLoad event of ASP.NET life cycle
throw an exception else continue execution of the method.
It is not clear which Onload event is meant, nor where the "method" resides. Is it the Page's Onload or a Control's OnLoad? Is it a Page's "method" or a Control's "method"?
Anyway, one can store sort of flag in the Context.Items Dictionary, which all controls (including Page) have access to during a request. This eliminates the need to use a general base page like suggested obove.
In the OnLoad method (no matter whether it is a Page's OnLoad or a Control's OnLoad):
Context.Items[UniqueID] = this;
In the "method":
if (Context.Items[UniqueID] != null)
{
throw new InvalidPageStateException();
}
This is a common need I have on every page:
if (session["LoggedIn"] == null || ((bool)session["LoggedIn"] != true))
....//user is not logged in. return.
I was wondering, is there a way I can create a class "Helper" with a method signature bool IsLoggedIn() and call that method from a page so that automatically it can check if the page it was called from has the session["LoggedIn"] set to true? Something like this:
class Helper
{
public bool IsLoggedIn()
{
System.Web.UI.Page page = ***FindCallerPageSomeHow***();
if(page.session["LoggedIn"] == null || ((bool)page.session["LoggedIn"] != true))
return false;
return ((bool)page.HpptContext.Session["LoggedIn"] == true);
}
}
Ofcourse, I could try implementing an interface for each codebehind class, but thats repetitive. Also, I could pass in the HttpContext for IsLoggedIn, but that's a bit of clutter..
Any ideas? Is there a simple-to-implement pattern for this?
If you want to use this approach I would probably add a extension method on the session. But using formsauthentication is usually a lot easier.
Update
Btw, here is the extension method:
public static bool IsSignedIn(this HttpSessionState session) {
//Use the session to check if the user is signed in
}
Then you can use it like this:
if(Page.Session.IsSignedIn()) {
//Code
}
You could always have a static class in a library somewhere, but my favorite technique is simply to create your own Page class and add properties or override events there.
public class myPage : System.Web.UI.Page
{
public void myPage()
{
}
public bool IsLoggedIn()
{
System.Web.UI.Page page = ***FindCallerPageSomeHow***();
if(page.session["LoggedIn"] == null || ((bool)page.session["LoggedIn"] != true))
return false;
return ((bool)page.HpptContext.Session["LoggedIn"] == true);
}
}
Then in the code behind of your actual page, you would have
public partial myAspxPage : myNamespace.myPage
{
}
As an example, my page class usually contains a public property called ValidUser that contains pertinent user information (so I don't have to keep looking it up). If that value is null, then I don't have one. If it's not, then I have what I need. Then whenever I create a new page in my site, I just have it inherit my page class instead of the default.
EDIT: Added your method in for a little more clarity.
Why not put the code in the master page? That way any pages that need to be tested for the user being logged in can inherit from that master page and all is handled automatically. Otherwise, you're just repeating yourself in the code for every page.
I would create a base class called BasePage which would inherit from System.Web.UI.Page. I would then have the codebehind class inherit from BasePage.
In BasePage, you just add a method called IsLoggedIn(), and you can call it from anywhere within your code behind class.