User Control to Excute Page Class Method (Dynamicly) - asp.net

I have many aspx pages which inherits a base Class.
base class has a method name "GetGroupID", This method returns different data depends which page i am on, now few pages need to override this method (which is fine).
Problem:
I have user control which is placed in almost all pages, now this user control Accessess GetGroupID method from page base class, which is fine as long as i know page class name, since I have so many pages, one base class and one user control...it would be niceif I can get Page Class name from UserControl and execute the base method dynamically.
Curreny I have following code which works within UserControl
Dim c As homepage = CType(Me.Page, homepage)
Call c.getGroupID
However in above example I know the Page Class name (homepage), but lets say i am on a different page which has a classname "portal", it would be impossible for me to keep track of so many pages.
I would like to excute the method in base class within user control, and I would like to override this method for certain pages.
please advise.

You could let the base-page implement a custom interface, for example IGroupable with a method GetgroupId. Then you only have to know in the UserControl that it's Page is IGroupable(either directly or through inheritance) and you know for sure that it has a method GetgroupId.
Public Interface IGroupable
Function GetGroupId() As Int32
End Interface
Class BasePage
Inherits Page
Implements IGroupable
Public Overridable Function GetGroupId() As Integer Implements IGroupable.GetGroupId
Return 1
End Function
End Class
Class ChildPage
Inherits BasePage
' default implementation of GetGroupId from base page '
End Class
Class SpecialPage
Inherits BasePage
' override it here since it has a different implementation than in the base page '
Public Overrides Function GetGroupId() As Integer
Return 2
End Function
End Class
You get the id in the UserControl in this way:
Class UserControl1
Inherits UserControl
Dim id As Int32 = DirectCast(Me.Page, IGroupable).GetGroupId()
End Class

Related

Cannot add property to INamingContainer in Web User Control

The code I have (below) works except for when I add the ref="abc" to the TemplateItem tag. When it is included I get this error:
Property 'TemplateItem' does not have a property named 'ref'
How do I resolve this issue?
Default.aspx
<%# Register Src="~/message.ascx" TagName="Message" TagPrefix="uc" %>
<uc:Message ID="msg" runat="server" abc="123" >
<TemplateItem ref="abc">Hi</TemplateItem>
</uc:Message>
message.ascx
<asp:placeholder runat="server" id="PlaceHolder1" />
message.ascx.vb
Partial Class message
Inherits System.Web.UI.UserControl
Public Property abc() As String
Sub Page_Init()
If TemplateItem IsNot Nothing Then
TemplateItem.InstantiateIn(PlaceHolder1)
End If
End Sub
Private m_TemplateItem As ITemplate = Nothing
<TemplateContainer(GetType(TemplateItem2))> _
Public Property TemplateItem() As ITemplate
Get
Return m_TemplateItem
End Get
Set(ByVal value As ITemplate)
m_TemplateItem = value
End Set
End Property
Public Class TemplateItem2
Inherits Control
Implements INamingContainer
Public Property ref() As String
End Class
End Class
Are you sure it should be:
Public Class TemplateItem2
at the bottom there, and not just the following?:
Public Class TemplateItem
(If you just want a different name from the property, maybe something like TemplateItemImplementation or just TemplateItemImpl would be more clear?)
Also, I'm not sure how this works:
TemplateItem.InstantiateIn(PlaceHolder1)
The MSDN page on CompiledTemplate.InstantiateIn() says: This API supports the .NET Framework infrastructure and is not intended to be used directly from your code. I guess this is a sidenote though, and I'm assuming you've gotten it to work the way you want...
I think the problem is related to the instantiation of TemplateItem in that line though; I can not see how TemplateItem2 (which contains the property ref()) is related to ITemplateItem. Maybe you just need to make TemplateItem2 also implement ITemplateItem?
Another thing to try is to make ref() a property of ITemplateItem, if possible. Maybe that Interface becomes the Type of <TemplateItem />, which would explain why it does not contain the property Ref?.
(That is assuming the type is specified by the return type of the property TemplateItem()).

access lable on main asp page from class

I have a lable I want to update on a web form page from another class. I created an instance of that class then referenced a public method to do the update since I was unable to access the lable control directly. But when it reaches the public method it seems as if the controls were initialized and are not recognizable.
*...' calling class*
dim kws as new form2class
kws.setErrorLable("ERROR FOUND" & ex.message.tostring)
.....
called class
public sub serrorLable(Byval msg as string)
label10.text=msg
end sub
Am I missing something here? Thanks in advance
You can access the current page like this:
Page currentPage = (Page)HttpContext.Current.Handler;
Depending on where the label is in the page, you may need to use recursion to find the Label, but the above code will get you to the current page.

access a public function in .ascx

how can i access a public function in an .ascx file using C#?
Thanks
If the function is not static you will need to first obtain an instance of the class containing the function and then invoke the function on this instance. For example:
<%
// obtain an instance of the type containing the function
Foo instance = new Foo();
// invoke the function on this instance
string result = instance.Bar();
%>
Obviously it would be better to do this in the code behind file instead of polluting your markup.
Like other public functions in .NET Framework - via object reference. But sometimes Visual Studio doesn't automatically see your User Control's public members. Try to rebuild your user control and the site if IntelliSense window doesn't show it to you.
Where are you calling the function from? The containing page? Masterpage? Parent control? The control itself? Regardless, you'll need to somehow obtain a reference to the control instance (unless the method is static) in order to invoke this method. And the type of your reference must match that of the class that defines the method.
Edit:
MyControl myControl = (MyControl)Page.FindControl("Id_Of_The_Control");
if (myControl != null)
{
myControl.TheMethod();
}
if you don't want to add your ascx control into a placeholder programmatically, just implement IAttributeAccessor and IUserControlDesignerAccessor interfaces to your user control class like;
public partial class yourascxclassname: System.Web.UI.UserControl, IAttributeAccessor, IUserControlDesignerAccessor
you can access only public members of your ascx control.

Extend System.Web.HttpContext.User

I would like to extend the System.Web.HttpContext.User object (ASP.NET/VB.NET) so that it contains other fields besides just Name. I understand I can create an object that inherits the System.Security.Principal.GenericPrincipal class, but how do I store that in the Current.User object in a usable fashion. ie, I can do something like Current.User.UserID.
So far to achieve this I've created a kludgy workaround by using | delimited strings in the User.Name property and then splitting them, but it's getting kind of ridiculous.
Any suggestions?
Thanks!
EDIT: I have tried the following to no avail:
Imports System.Security.Principal
Public Class CurrentUser : Inherits GenericPrincipal
Private _totalpoints As Integer
Private _sentencecount As Integer
Private _probationuntil As DateTime
Public ReadOnly Property TotalPoints() As Integer
Get
Return _totalpoints
End Get
End Property
Public ReadOnly Property SentenceCount() As Integer
Get
Return _sentencecount
End Get
End Property
Public ReadOnly Property ProbationUntil() As DateTime
Get
Return _probationuntil
End Get
End Property
Public Sub New(ByVal principle As IIdentity, ByVal roles() As String, _
ByVal points As Integer, ByVal sentences As Integer, ByVal probationTil As DateTime)
MyBase.New(principle, roles)
_totalpoints = points
_sentencecount = sentences
_probationuntil = FixDBNull(probationTil)
End Sub
End Class
setting the object in my Global.asax Application_AuthenticateRequest function like so:
HttpContext.Current.User = New CurrentUser(User, userRoles, _
points, sentenceCount, probationUntil)
with a direct cast wherever the object is needed like so:
Dim thisUser As CurrentUser = DirectCast(Current.User, CurrentUser)
i also tried CType and it didn't work... my error is
[InvalidCastException: Unable to cast object of type 'System.Security.Principal.GenericPrincipal' to type 'myProject.CurrentUser'.]
i'm losing my mind here ... :( thanks guys...
anyone?
You can create your own Principal class with the required properties, that inherits from a Generic Principal, and then set the User property of your Current Context to be the a user of that type.
The example below is for ASP.Net MVC but a similar approach could be used with webforms.
You can do this in the PostAuthenticateRequest after a user is authenticated (in the Global.asax)
private void MvcApplication_PostAuthenticateRequest(object sender, EventArgs e)
{
SomePrincipal newUser = new SomePrincipal(User.Identity, tmpRoles);
senderRef.Context.User = newUser;
System.Threading.Thread.CurrentPrincipal = newUser;
}
You could then add a property or method in a base class of your page (or controller) for example that to wrap and type the Context.User principal to your Principal type and make sure you call it rather than calling the one on the HttpContext.
There are probably other solutions too!
Would this approach work for you? It looks a little involved but it really doesn't take too long to setup:
Create a 'base' class of your own, and have your pages inherit from that. For example, create a base class called 'BasePage' which inherits from System.Web.UI.Page.
Have your ASP.net pages inherit from your new BasePage class.
In the BasePage class, you can have a public property which contains the extra fields you want to store for your user (eg. BasePage.FirstName, BasePage.LastName). Better still, create a User object containing the extra fields, and expose that via BasePage, eg. "BasePage.Customer". This keeps things tidy if you plan to extend BasePage later.
You can then override the OnInit() of the base class to check for HTTPContext.Current.User.Name property, and fetch the necessary info from your DB to initialise your custom properties.
You can modify the code so that it won't need to hit the database each time the page is refreshed by using ControlState to check whether the custom fields have values before populating them again from the database.
Hope this helps...
Richard.

Generics on ASP.NET page Class

I want to implement Generics in my Page Class like :
Public Class MyClass(Of TheClass)
Inherits System.Web.UI.Page
But for this to work, I need to be able to instantiate the Class (with the correct Generic Class Type) and load the page, instead of a regular Response.Redirect. Is there a way to do this ?
I'm not sure to fully understand what you want to do.
If you want something like a generic Page, you can use a generic BasePage and put your generic methods into that BasePage:
Partial Public Class MyPage
Inherits MyGenericBasePage(Of MyType)
End Class
Public Class MyGenericBasePage(Of T As New)
Inherits System.Web.UI.Page
Public Function MyGenericMethod() As T
Return New T()
End Function
End Class
Public Class MyType
End Class
The answer that says to derive a type from the generic type is a good one. However, if your solution involves grabbing a page based upon a type determined at runtime then you should be able to handle the PreRequestHandlerExecute event on the current HttpApplication.
This event is called just before a Request is forwarded to a Handler, so I believe you can inject your page into the HttpContext.Current.Handler property. Then you can create the page however you wish.

Resources