Using a class like a public variable in asp.net - asp.net

I'm getting an error in .net when trying to declare a Public class on my code behind page.
Partial Class _Default
Inherits System.Web.UI.Page
Public someVariable as integer
Public someClass as className
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load [...]
The error I'm getting is BC30508: 'someClass' cannot expose type 'className' in namespace '<Default>' through class '_Default'.
The goal here is accessing the class properties in script blocks on the aspx page like this <%=someClass.classProperty%>
I'm not sure if I'm trying the right methods (I've tried several ways of declaring the public class) or if it can even be done... Thanks for taking a look at it.

Check the protection level of your className type. Did you forget to mark it public?
That error message means you have something that is has restricted access, and you are trying to use it in a way that would allow access outside the restrictions. For example, if your className type is internal or a private child class of _Default, but you add a public member of that type as a property your assembly would expose a type as part of it's interface that is otherwise unusable.

It's almost certainly the declaration of your "className" class. Try setting it to public.

Check the protection level of the _Default class. It might not be setup as a partial class and that will result in your protection level issue that you are seeing.

Related

Code-behind properties inaccessible at design time but do work properly at runtime

I have to make some changes to a legacy ASP.NET website. It has a Property declaration like this:
Public ReadOnly Property Foo As String
Get
If Not Session("Foo") Is Nothing Then
Return Session("Foo").ToString()
Else
Return ""
End If
End Get
End Property
At design-time, looking at some javascript on the markup page, the property is inaccessible, although it works properly at run-time. That wrinkle makes this question a little different from others like it which have been asked here.
var f = <%= Foo %>;
In the Visual Studio editor, Foo is underlined in red; the error shown in the tooltip: Foo is undeclared. It may be inaccessible due to its protection level.
All of the properties on the page are inaccessible, not just this one.
What could be causing that spurious error at design-time?
EDIT: Here's some new info:
On an object declaration on the page, I am getting this error:
Private WithEvents MyGizmo as Gizmo
Class MyAssemblyName.Gizmo
MyAssemblyName -- Not Available
MyAssemblyName -- Available
I do not understand it. MyAssemblyName is mentioned twice, once as not available and once as available.
END OF NEW INFO
I've checked the page declaration:
MyAssemblyName matches the assembly name and the root namespace as shown on the Project Properties page.
The application type is Class Library.
I've checked the class declaration for protection level:
Public Class Widgets
End Class
and have made sure that the Web Form Designer Generated Code is present:
#Region " Web Form Designer Generated Code "
'This call is required by the Web Form Designer.
<System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
End Sub
'NOTE: The following placeholder declaration is required by the Web Form Designer.
'Do not delete or move it.
Private designerPlaceholderDeclaration As System.Object
Private Sub Page_Init(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Init
'CODEGEN: This method call is required by the Web Form Designer
'Do not modify it using the code editor.
InitializeComponent()
End Sub
#End Region
What else to check?

Trying to understand how SyncLock Works

I made a two static classes
NotInheritable Class gObject2
Public Shared TestSyncLock As String = "test"
End Class
NotInheritable Class gObject3
Public Shared TestSyncLock As String = "test"
End Class
Then I have two aspx
Synclock1.aspx:
Public Class SyncLock1
Inherits System.Web.UI.Page
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
SyncLock gObject2.TestSyncLock
Thread.Sleep(10000)
End SyncLock
End Sub
End Class
Synclock2.aspx
Public Class SyncLock2
Inherits System.Web.UI.Page
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
SyncLock gObject3.TestSyncLock
SomeDiv.InnerHtml = "It works"
End SyncLock
End Sub
End Class
When I go to synclock1.aspx it spins for 10 seconds and shows a blank page as expected.
When I go to synclock2.aspx it spits out it works
Everything is good so far.
Now when I go to synclock1.apx and then in another browser got to synclock2.aspx, synclock2.aspx doesn't finish loading until synclock1.aspx finishes.
These are 2 different objects I'm locking with synclock, but it treats them the same. Why is this?
The SyncLockstatement takes an object reference as its argument. As the String type is a reference type, your code is satisfying that constraint. However, due to String Interning in .Net, the literal value equality of the two separate String references is also causing referential equality between gObject2.TestSyncLock and gObject3.TestSyncLock.
From: String.IsInterned Method - Remarks (emphasis added)
The common language runtime automatically maintains a table, called
the intern pool, which contains a single instance of each unique
literal string constant declared in a program, as well as any unique
instance of String you add programmatically by calling the Intern
method.
The intern pool conserves string storage. If you assign a literal
string constant to several variables, each variable is set to
reference the same constant in the intern pool instead of referencing
several different instances of String that have identical values.
Since both gObject2.TestSyncLock and gObject3.TestSyncLock are pointing to the same String reference, SyncLock gObject2.TestSyncLock will block SyncLock gObject3.TestSyncLock.
The subject code is a good example of how string interning can cause unexpected behavior. The article Interning Strings and immutability provides additional details on the mechanics of interning and also provides another example where interning can cause unexpected results.
So the moral of this story is to avoid using strings as the argument for SyncLock. It is safer to use something like the following:
NotInheritable Class gObject2
Public Shared TestSyncLock As New Object
End Class
NotInheritable Class gObject3
Public Shared TestSyncLock As New Object
End Class

Use ASP.net 2010 B to Ping an IP Address

I'm trying to use a simple Ping technique to ping an IP Address. I have added Imports System.Net.NetworkInformation.Ping to my web page and tried to simply create a button that once clicked ping an IP address.
The problem that I have is an error message that states 'System.Net.NetworkInformation' is a namespace and cannot be used as an expression.
I'm new to this and have tried to replace this with something else, but I still cannot seem to get this to work. Would it be possible for someone to review this and let me know where I'm going wrong. Im using VB and VS2010. This is my code:
Imports System.Text
Imports System.Net.NetworkInformation.Ping
Partial Class Ping
Inherits System.Web.UI.Page
Protected Sub btnPing_Click(sender As Object, e As System.EventArgs) Handles btnPing.Click
Using System.Net.NetworkInformation
Ping(Ping = New Ping())
PingReply(pingReply = Ping.send("xxx.xx.xxx.xx"))
Console.WriteLine("Address: {0}", pingReply.address)
Console.WriteLine("Status: {0}", pingReply.Status)
End Using
End Sub
End Class
You would be better off trying the following:
Imports System.Text
Imports System.Net.NetworkInformation
Partial Class Ping
Inherits System.Web.UI.Page
Protected Sub btnPing_Click(sender As Object, e As System.EventArgs) Handles btnPing.Click
Dim vPing As New Ping
Dim vPingReply As PingReply = vPing.Send("xxx.xx.xxx.xx")
Console.WriteLine("Address: {0}", vPingReply.Address)
Console.WriteLine("Status: {0}", vPingReply.Status)
End Sub
System.Net.NetworkInformation is just a namespace, it just serves as a container for other classes.
You've named your page class Ping, which is the same name as the .NET class you are instantiating.
Partial Class Ping
Inherits System.Web.UI.Page
Elsewhere in your code, you try to use the .NET Ping class.
I know that this can cause issues in certain project types.
Try naming your page PingPage instead *.
*As well as the other suggestions here about Namespaces etc.

Shared Variables lifetime

When are Shared (Static) variables created and destroyed. For example have a look at the code below:
Imports System.Data.SqlClient
Public Class Form1
Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Person.testCon = New SqlConnection
Person.Age = 30
Dim p1 As Person
End Sub
End Class
Imports System.Data.SqlClient
Public Class Person
Public Shared testCon As SQLConnection
End Class
The testCon variable is accessible from the Form_Load before the first instance of Person is created. I realise that it is probably not good practice to have a connection as a shared variable but I want to get my point across. I also want to know when variables are created and destroyed if they are primitives (like Person.Age in the example)
Shared variables live for the length of your application, according to Microsoft.
However, object type variables are only instantiated when you tell them to be.
You can verify this behavior by creating a new test class:
Public Class Class1
Sub New()
System.Diagnostics.Debug.Fail("Class Created")
End Sub
End Class
Then create a shared variable for this class as a member variable in another class:
Private Shared m_TestClass As Class1
If you don't access the shared variable, the Debug.Fail statement will not be executed. However, as soon you instantiate this class and assign it, it will be fired (just like any other object):
m_TestClass = New Class1
Shared variables live until the AppDomain they reside in is unloaded.
You could also test this by adding a Finalize statement to the test class with a similar Debug.Fail statement.
The lifetime is one reason that you should use SyncLock when assigning new values to object-type shared variables.

Access Parent Page Property from User Control

Trying to access a property from the parent page on my user control.
Here's the start of my default.asp codebehind:
Partial Class _Default
Inherits System.Web.UI.Page
Private _selectedID As String = "74251BK3232"
Public Property SelectedID() As String
Get
Return _selectedID
End Get
Set(ByVal value As String)
_selectedID = value
End Set
End Property
Here's the start of my user control codebehind:
Partial Class ctrlAddAttribute
Inherits System.Web.UI.UserControl
Dim selectedID As String = Me.Parent.Page.selectedID()
I'm getting the error "selectedID is not a member of System.Web.UI.Page"
Please adivse!
You could access the property when you cast the Page to your actual implementaion called _Default.
Dim selectedID As String = DirectCast(Me.Page,_Default).selectedID()
But that is not the purpose of a Usercontrol(reusability).
Normally you would give the ID from the Controller(page) to the UserControl.
So define a property in the UserControl and set it from the page.
On this way the UserControl would still work in other pages.
Because the user control doesn't belong to the page, you can't access it directly unless you either explicitly set a property in the usercontrol from the including page or create a recursive function that cycles through all of the parent objects until it finds an object of type System.Web.UI.Page.
For the first, you could use a property (I've done this using a property called ParentForm) in the user control:
Private _parentForm as System.Web.UI.Page
Public Property ParentForm() As System.Web.UI.Page ' or the type of your page baseclass
Get
Return _parentForm
End Get
Set
_parentForm = value
End Set
End Property
In the "Parent" page, you would set this property in an event as early as possible. I prefer to use PreLoad because it comes before the load (thus is available when most other controls would need it) and after the init.
Protected Sub Page_PreLoad(ByVal sender as Object, ByVal e as EventArgs) Handles Me.PreLoad
Me.myUserControlID.ParentForm = Me
End Sub
You could also write a function trolls through the parent controls to find the page. Following code is untested so it may require tweaking, but the idea is sound.
Public Shared Function FindParentPage(ByRef ctrl As Object) As Page
If "System.Web.UI.Page".Equals(ctrl.GetType().FullName, StringComparison.OrdinalIgnoreCase) Then
Return ctrl
Else
Return FindParentPage(ctrl.Parent)
End If
End Function
EDIT: You also can't access this property directly because it does not exist within the type System.Web.UI.Page. As #Tim Schmelter recommends, you can either attempt to cast the page to the specific page type _Default or if this is something common to many of your pages, you may need to create a base page class and include your property in that class. Then you can inherit this class instead of System.Web.UI.Page
Public Class MyBasePage
Inherits System.Web.UI.Page
Public Property SelectedID() as Integer
...
End Property
End Class
Then in the page:
Partial Class _Default
Inherits MyBasePage
...
End Class

Resources