ASP.Net User Control public function is not a member - asp.net

I have a user control on a Web Site with this inside.
Namespace MenuTreePanel
Public Class MenuTreePanel
Inherits System.Web.UI.UserControl
Public root As New MenuNode(0, 0, "root", "")
Public WithEvents Spany1 As HtmlGenericControl = New HtmlGenericControl("UL")
Public WithEvents Spany2 As HtmlGenericControl = New HtmlGenericControl("UL")
Public WithEvents Spany3 As HtmlGenericControl = New HtmlGenericControl("UL")
Public Function getRoot() As MenuNode
Return root
End Function
End Class
End Namespace
When I go to access the getRoot function I get Error
'getRoot' is not a member of 'ASP.MenuTreePanel'.
The namespace is incorrectly labelled as ASP, and I was wondering where that might be coming from. In the object explorer, my control is listed under both the correct namespace and the ASP namespace.
Referenced on the page using
<%# Register TagPrefix="MenuTreePanel" Src="~/MenuTreePanel.ascx" TagName="MenuTree" %>
<MenuTreePanel:MenuTree ID="menuTreeSelect" runat="server"></MenuTreePanel:MenuTree>
Edit 2:
<%# Control Language="vb" CodeBehind="~/MenuTreePanel.ascx.vb"className="MenuTreePanel" %>
and the attempt to access it
Dim root As New MenuNode(0, 0, "root", "")
root = (menuTreeSelect).getRoot()

The problem is likely that you're attempting to access the property statically. My assumption is that you do not want to access it statically, since it's a control.
My suggestion is that you look at how you're using the MenuTreePanel object.
You should be accessing it like this:
menuTreeSelect.getRoot();
and not like this:
MenuTreePanel.getRoot();

Try:
Public Shared Function getRoot() As MenuNode
Return root
End Function

I wasn't linking the CodeFile and the ASCX correctly with a Web Site.
I had to change CodeBehind to CodeFile and add an inherits, and now everything is working correctly.
Thanks for your help.

Related

How to wire up simple Web API controller in global.asax

I have a simple Web API (sitting inside webforms site) that generates a simple "Tip of the Day". The code is as follows:
AppCode\TipOfTheDayController.vb
Imports System.Net
Imports System.Web.Http
Public Class TipOfTheDayController
Inherits ApiController
Private Function GenerateTip() As TipOfTheDay
Dim tipCol As New List(Of Tip)
tipCol.Add(New Tip("Tip Text 01"))
tipCol.Add(New Tip("Tip Text 02"))
tipCol.Add(New Tip("Tip Text 03"))
Dim rnd As New Random
Dim i As Int16 = rnd.Next(0, tipCol.Count - 1)
Dim td As New TipOfTheDay
td.TipString = tipCol(i).TipString
td.TipNumber = i
Return td
End Function
Public Function GetTip() As TipOfTheDay
Return GenerateTip()
End Function
End Class
Public Class Tip
Public Property TipString As String
Public Sub New(ts As String)
Me.TipString = ts
End Sub
End Class
Public Class TipOfTheDay
Public Property TipString As String
Public Property TipNumber As String
End Class
I am trying to wire this up so that it can be called using
http://www.mysite.com/api/tips
Assuming the above URL is okay, I cannot figure this bit out in Global.asax. I've seen loads of examples online but all have an optional "ID" value which I don't need. Can anyone please show me what I need to do to retrieve my random "tip" from the API?
<%# Application Language="VB" %>
<%# Import Namespace="System.Web.Routing" %>
<%# Import Namespace="System.Web.Optimization" %>
<%# Import Namespace="System.Web.Http" %>
<script runat="server">
Sub RegisterRoutes(routes As RouteCollection)
routes.MapHttpRoute("TipOfTheDay", "api/tips")
End Sub
</script>
The routing is looking for an Index Action on your controller if the action was not specified in the route or by entering into the url. Rename your GetTip function to Index.
If that is not acceptable, you can add a route similar to the following in lieu of your current route.
routes.MapHttpRoute("TipOfTheDay", "api/tips", new { Controller = "TipOfTheDay" Action = "GetTip" });
I wouldn't recommend this route, however, since it will try to use GetTip as the default action every time one is not specified.
Here is a good resource for routing in a web forms application:
http://msdn.microsoft.com/en-us/library/dd329551.ASPX

How to Invoke function in user control from parent page asp.net

Asp.Net 4.0
Is it possible to call a function in a user control from the parent page in code behind?
The user controls are created by other programmers, however each will have a common public function that i look for called "Output" which returns values in need for the main page. The main page has a main menu, so only one user control will display based upon the main menu selection.
Folder in WebApp with user controls:
> UserControls
ProductA.ascx
ProductB.ascx
ProductC.ascx
ProductD.ascx
etc...
Code behind when user clicks a menu button:
Dim product As string = Session("MenuProduct")
Dim uc As UserControl
uc = LoadControl("~/UserControls/" & product & ".ascx")
InputPanel.Controls.Add(uc)
Function in user control I would like to access. This will be a common Function.
Public Function Output(ByVal ParamArray expr() As Object) As Object
...code
End Function
You can call functions in a userControl from a parent page if they have the right access modifier. Public I believe
Dim product As string = Session("MenuProduct")
Dim uc As UserControl
uc = LoadControl("~/UserControls/" & product & ".ascx")
InputPanel.Controls.Add(uc)
if (uc is TypeWithMethod )
{
Dim ucTyped As TypeWithMethod
ucTyped = uc As TypeWithMethod
ucTyped.Method()
}
Vb syntax is rusty, kept putting ; after every line.
Here are little details to what andrew is talking about...
Public Interface IGroupable
Function GetGroupId() As Int32
End Interface
Class MyUserControl
Inherits UserControl
Implements IGroupable
Public Function GetGroupId() As Integer Implements IGroupable.GetGroupId
Return 1
End Function
End Class
Class MyPage
Inherits Page
Dim id As Int32 = DirectCast(myUserControl, IGroupable).GetGroupId()
End Class
So basicly create a Interface, have all of your user controls implement that interface, and then when you load any of your user controls within webpage...simply CAST them to the the type of your interface name....your interface will have the access to the function.

Getting a ScriptReference from a ScriptResourceMapping definition in a custom control

I am building a custom control with client side scripts that I would like to reference using ScriptManager.ScriptResourceMapping (to make use of the Path and DebugPath attributes).
I would like the custom control to be easily ported to other projects - i.e. I would like to drag and drop the codebehind files (and eventually make the control a separate DLL, but for now the drag and drop will suffice). I would therefore like to avoid (1) having the client script as an embedded resource, (2) referenced as a WebResource in the AssemblyInfo, or (3) have the ScriptManager.ScriptResourceMapping.AddDefinition in global.asax.
In simple terms can I get the script management code to be in just the custom control's code?
At the moment I am getting an error stating that the script reference cannot be found in the assembly, and I guess I am setting the wrong assembly.
My custom control code is as follows:
Public Class MyControl
Inherits System.Web.UI.LiteralControl
Implements ISectionControl, IScriptControl
Private _scriptReference As ScriptReference
Public Sub New()
' Add the resource mapping
ScriptManager.ScriptResourceMapping.AddDefinition("MyControlScript", New ScriptResourceDefinition With {
.ResourceAssembly = System.Reflection.Assembly.GetExecutingAssembly,
.ResourceName = "MyControlScript.js",
.Path = "Path.To.MyControlScript.minimised.js",
.DebugPath = "Path.To.MyControlScript.original.js"
})
' Set the script reference
_scriptReference = New ScriptReference("MyControlScript.js", Assembly.GetExecutingAssembly.FullName)
End Sub
Protected Overrides Sub OnPreRender(e As System.EventArgs)
MyBase.OnPreRender(e)
' Register the script
ScriptManager.GetCurrent(Page).RegisterScriptControl(Of MyControl)(Me)
' Some code to set the Text of the literal control
' ...
End Sub
Public Function GetScriptDescriptors() As System.Collections.Generic.IEnumerable(Of System.Web.UI.ScriptDescriptor) Implements System.Web.UI.IScriptControl.GetScriptDescriptors
Return New ScriptDescriptor() {}
End Function
Public Function GetScriptReferences() As System.Collections.Generic.IEnumerable(Of System.Web.UI.ScriptReference) Implements System.Web.UI.IScriptControl.GetScriptReferences
Return New ScriptReference() {_scriptReference}
End Function
End Class
I hope the question makes sense. Thanks for taking the time to read through.
Ali
Answered this myself, I was getting confused with the assemblies and the constructors for ScriptReference. I just wanted a ScriptReference with the (mapped) name so I used the blank constructor and then set Name. I could then remove the assembly information.
Adjusting the following sorted the problem out:
Public Sub New()
' Add the resource mapping
ScriptManager.ScriptResourceMapping.AddDefinition("MyControlScript", New ScriptResourceDefinition With {
.Path = "Path.To.MyControlScript.minimised.js",
.DebugPath = "Path.To.MyControlScript.original.js"
})
' Set the script reference
_scriptReference = New ScriptReference() With {.Name="MyControlScript"}
End Sub

DateTime.Parse using culture en-us, despite web.config setting

Question:
in web.config
in section
system.web
I have
<globalization culture="de-ch" uiCulture="de-ch" requestEncoding="UTF-8" responseEncoding="UTF-8"/>
What I want is to parse a string like this
"20.03.2012 00:00:00"
to a datetime value
but
DateTime dtAsIs = DateTime.Parse("20.03.2012 00:00:00")
throws an exception
Unfortunately only on the testserver, not on my development system.
I do not have access to the testserver, except to copy the webapp over into a windows share.
I can reproduce the exception like this:
DateTime dtThrowsException = DateTime.Parse("20.03.2012 00:00:00",new System.Globalization.CultureInfo("en-us"));
Whereas it works fine like this:
DateTime dtWorks = DateTime.Parse("20.03.2012 00:00:00",new System.Globalization.CultureInfo("de-ch"));
I checked the ASP page, and there is NO culture set in the asp page
(I mean this:
<% #Page Culture="fr-FR" Language="C#" %>
)
If I set
System.Threading.Thread.CurrentThread.CurrentCulture
and
System.Threading.Thread.CurrentThread.CurrentUICulture
to de-ch at the very start of Page_Load like this
System.Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo("de-ch");
System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo("de-ch");
then it works fine.
The browser language is set to "de-ch", I checked that.
Can anybody tell my why the thread-culture gets set to English ?
I mean the obvious reason is that the server operating system is English, but I can't change that one, only settings in web.config.
I have the same experience as you, it seems that the globalization tag in web.config is simply ignored.
But since you always want to parse dates in the de-ch culture, I don't see what's wrong with just providing the culture to the DateTime.Parse method (some guidelines say this is the best thing to do anyway)
The problem seems to be that ASP.NET overwrites the culture even when you explicitly specify it.
(Like
DateTime.Parse("Whatever", New System.Globalization.CultureInfo("de-ch"))
)
one needs to force override it
New System.Globalization.CultureInfo("de-ch", False)
So in order to make it configurable and change it as few as possible, you need to get the culture from web.config with
System.Globalization.CultureInfo.CurrentCulture.Name
and then force set it with
DateTime.Parse("Whatever", New System.Globalization.CultureInfo(System.Globalization.CultureInfo.CurrentCulture.Name, False))
Note the overload with false, it's necessary, otherwise it doesn't really work.
Here is my solution:
Namespace ASP.NET.Sucks
Public Class PageWithCorrectPageCulture
Inherits Web.UI.Page
Protected Sub New()
System.Threading.Thread.CurrentThread.CurrentCulture = New System.Globalization.CultureInfo(System.Globalization.CultureInfo.CurrentCulture.Name, False)
System.Threading.Thread.CurrentThread.CurrentUICulture = New System.Globalization.CultureInfo(System.Globalization.CultureInfo.CurrentCulture.Name, False)
End Sub
End Class
End Namespace
Then, in the codebehind, replace System.Web.UI.Page with PageWithCorrectPageCulture
Partial Class whateverpage
Inherits PageWithCorrectPageCulture
'Inherits System.Web.UI.Page
And for those who can only copy-pase C#:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
namespace ASP.NET.Sucks
{
public class PageWithCorrectPageCulture : Web.UI.Page
{
protected PageWithCorrectPageCulture()
{
System.Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo(System.Globalization.CultureInfo.CurrentCulture.Name, false);
System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo(System.Globalization.CultureInfo.CurrentCulture.Name, false);
}
}
}

Need to reference controls/properties in an ascx control (asp.net, written in vb)

I have a user control that I'm adding to a webpage dynamically. The ascx has a couple of controls that I want to have access to at runtime. I can access the ascx itself, but none of the controls on the ascx are available. I have tried adding a simple public variable and also tried adding a public property to the ascx, but I am unable to get access to either of them at design time (compile errors). I would appreciate any ideas - I'm stuck... :-)
I added the following to the code-behind of the ascx control:
Public Property areaCode() As String
Get
Return iebEmpPhoneAreacode.Text
End Get
Set(ByVal value As String)
iebEmpPhoneAreacode.Text = value
End Set
End Property
Public AreaCodeStr As String = ""
and am trying to use variations of the following to access the property/ascx controls:
For Each ctrl As Control In pnlPhones.Controls
If ((TypeOf ctrl Is ctrlPhone) And (ctrl.ID = vbNullString)) Then
(DirectCast(ctrl, ctrlPhone)).AreaCodeStr = "test"
'or try this
ctrl.areaCode = "test"
End If
Next
The hosting page should have an #Reference Directive pointing to the loaded ascx so it will be compiled with the page.
Something like:
<%# Reference VirutalPath="YourReferenceControl.ascx" %>
This should go in the directives area somewhere below the #Page directive.
http://msdn.microsoft.com/en-us/library/w70c655a.aspx

Resources