Unable to access class from app_code - c#

I have a web site(not web app) which has a default.aspx and default.aspx.cs.
And it has an App_Code folder with class A in it.
So default.aspx.cs. Looks like:
namespace test1
{
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
}
}
And class A:
namespace test1
{
public class A
{
_Default mDefaultRef;
public pageLogicIndividual(_Default defaultRef)
{
mDefaultRef = defaultRef;
}
}
}
I can use A in _Default. eg. if I type test1., while working in class _Default, the IntelliSense will show both classes.
But if I type test1., while working in class A, the IntelliSense will only show A.
Why can't I use _Default in A?
Error : the type or namespace name does not exist in the namespace
(are you missing an assembly reference )
Edit:
I'll try to clarify.
While working in the .cs file where class _Default resides I can type test1., which is the namespace, and the intellisense will show me class _Default and Class A.
But if I'm working in the .cs file where class A resides and type test1., which is the namespace, then the intellisense will only show me class A.

I have had this challenge in the past.
Open up the App_Code folder node in Visual studio.
Right click on the concerned class, then click properties
In the properties pane, change Build Action to Compile.
It should work fine now.

Your problem is with your misleading namespace that you've added yourself after the new file has been created because ASP.NET Web Sites do not have namespace. The namespaces are available in Web Applications projects. i.e. after a new WebSite is created, namespace doesn't added to the files.
So you don't need to place your class A inside the test1 namespace because you can use A in default.aspx.cs even without namespace but you can not access other WebForm page classes from a Webform page or App_Code classes.
BTW if you want to use the necessary and reusable methods within a class of the Default Web Form, you can move those methods out to A class which is under App_Code and as I said already you can use it within all the Web Form CodeFiles without providing namespace for it.

In a nutshell, you cannot access page classes from App_code classes.
This restriction comes from website project compilation model. Special App_code folder contains shared classes (and possibly other resources) which are available to pages (and to each other). During compilation App_code is compiled first in a single assembly. This is the key point. Pages, controls and MasterPages are compiled in another assembly(ies) which may have references to the App_code assembly (but not vise versa). So this is one-way road.
No namespace declaration should circumvent this behavior.
Pages can see each other in ASP namespace (ASP.default_aspx) but pages usually don't have public properties / methods (user controls .ascx usually have).
Read better explanation on MSDN Code-Behind Pages

Related

c#: Problems with the namespaces

I am having a problem with Visual Studio 2015 and Framework 4.6.1.
I have a business layer with this namespace: BusinessLayer.LocalStorage. In this class (named LocalStorage) I have this function:
...
public static void XXX()
{
}
...
In the main project with the same Framework 4.6.1, I have in one Winform
using BusinessLayer.LocalStorage;
In the Load I wrote the function but the reference is not recognized:
I have to add LocalStorage before:
LocalStorage.LocalStorage.XXX();
This way the call is working
why is not working using LocalStorage.XXX()? I declared my namespace in the using clausules.. Then should be working.
I have the class in a directory inside BusinessLayer project for this reason namespace should be BusinessLayer.LocalStorage
Code is:
namespace BusinessLayer.LocalStorage
{
public class LocalStorage
{
...
public static void XXX()
{
}
...
}
}
This is because LocalStorage is ambiguous, it could either be namespace LocalStorage or the class LocalStorage. You can solve this in 3 ways:
Remove the namespace LocalStorage entirely and move everything in it inside the BusinessLayer namespace
Rename the class LocalStorage to something else
Add using LocalStorage = BusinessLayer.LocalStorage.LocalStorage to the top of your file where you need to use the class LocalStorage
Edit: Option 4. If you desperately want to keep the directory structure as it is right now (with a LocalStorage directory), you can alternatively tell Visual Studio that the directory LocalStorage is not a namespace provider. You can do this by editing the properties of the folder in the Solution Explorer
Visual studio automatically generates Namespaces based on the current location of a class within a solution. When you create a new class it first takes the name of the project. Then it takes the current folder the class is located in. it will continue appending the folder name to the namespace until it reaches the class name itself.
So for example, if you have a project called ExampleProject, with a folder called Models, with a class inside called BaseModel.cs, the resulting namespace would be ExampleProject.Models
Make sure the namespace containing XXX is not LocalStorage.LocalStorage and is called BusinessLayer.LocalStorage. You can change this namespace to whatever you want and rebuild your project.
Although the namespace structure and object names are not recommended to be the same, which will lead to errors in many cases, I see that you want to use it this way from the comments you made.
I don't recommend you to name a class like its namespace, see this article
I would recommend would be <XYZ>LocalStorage.cs
I don't know your layer structure, but you can call it LocalStorage.XXX () with a structure like the one below.
BusinessLayer structure:
LocalStorage Class:
namespace BusinessLayer.LocalStorage
{
public class LocalStorage
{
public static void XXX()
{
}
}
}
And finally, after referencing BusinessLayer to winForm, you can call it in Load method as follows.
using System;
using BusinessLayer.LocalStorage;
using System.Windows.Forms;
namespace WindowsFormsApp1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
LocalStorage.XXX();
}
}
}
Or, if you don't want a folder in your BusinessLayer structure, you can use it using the same namespace (namespace BusinessLayer.LocalStorage) as below.

How to reference UserControl?

I work on an application that has a particular design flaw, where some content should be accessible in multiple areas of the application depending on what role(s) a user may have. In the past this has led developers to copy and paste pages into different places with slightly different names, which ultimately leads to bugs when things get out of sync and also just feels yucky.
I want to try to abstract out the (99%) common code into its own class, however the code behind each page references various controls on the page. I can't seem to figure out how to reference the UserControl classes.
For example a page might have
<%# Register Src="~/uc/ResearchParamBar.ascx" TagName="ResearchParamBar" TagPrefix="uc1" %>
...
<uc1:ResearchParamBar ID="ResearchParamBar1" runat="server"/>
And the code behind would have
private void InitializeComponent()
{
// wire the event to the destination user control handler
ResearchParamBar1.SourcePageID = ObjectID;
...
}
The user control is defined like
public partial class ResearchParamBar : BaseUserControl
I was trying to pass a ResearchParamBar in the constructor to the abstract class, but it's not clear to me how to reference that class.
The type or namespace name 'ResearchParamBar' could not be found (are you missing a using directive or an assembly reference?)
public abstract class SummaryBase : WRBasePage
{
public abstract string ObjectID
{
get;
}
//Cannot figure out how to reference ResearchParamBar
private ResearchParamBar ResearchParamBar1;
public SummaryBase(ResearchParamBar researchParamBar)
{
ResearchParamBar1 = researchParamBar;
}

Cannot access BLL Class on ASP.NET

I'm creating a Web Application on ASP.NET and C#.
The problem I have is that I cannot create a instance of a BLL class on the code behind of a page.
I have the Log In Page (LogIn.aspx) and the page that controls de Log In Page (LogIn.aspx.cs). When I am on LogIn.aspx.cs and I try to do: UsersBLL _users = new UsersBLL(), I get the missing a using directive or assembly reference message.
I can fix it by rigth-clicking on UsersBLL.cs class > Properties > Build Action and changing Content to Compile.
At this point I can create an instance of UsersBLL.cs class on LogIn.aspx.cs, but the class get "broken" and does not recognize any "DataSet Instructions" (refer the image to understand it...)
What should I do to fix it?
Thankyou in advance for your answer!
"Broken" UsersBLL.cs class
You need to check what namespace is defined for your USERSTableAdapter, what is your assembly of this class. Add reference to this assembly. Then add the namespace of the adapter in your class UsersBLL. If this USERSTableAdapter is defined in the current project then only the namespace added required. For more help on using ADO.NET and TableAdapters in Visual Studio see this manual

Inaccessible public classes

I'm using a public LoginContext class to manage user logins in my web app.
Unfortunately, even though I have the LoginContext class declared publicly, my partial class Login at Login.aspx.cs can't seem to access it.
My code is as follows:
// ~/App_Code/LoginContext.cs
namespace stman
{
public class LoginContext
{
}
}
// ~/Login.aspx.cs
namespace stman
{
public partial class Login : System.Web.UI.Page
{
protected void btnLogin_Click(object sender, EventArgs e)
{
LoginContext log = new LoginContext(); // error is here
}
}
}
The error that comes up on the line where I instantiate LoginContext reads as follows:
The type or namespace name 'LoginContext' could not be found (are you missing a using directive or an assembly reference?)
When I try to generate a new class for LoginContext, it goes into the web app's root folder where it can no longer access the public Database class that I need in LoginContext.
I have no idea what's causing all of these problems, but based on what I've learned over the last 18 months doing this professionally, they shouldn't exist right now...
Can anyone help clear things up here? Specifically I'd like to know:
What I'm doing wrong
Why it's wrong
Who can I fix it?
Thanks in advance!
EDIT
I've had a look and it seems neither the Database class in ~/App_Code/Database.cs or the LoginContext class in ~/App_Code/LoginContext.cs are accessible to the page - or any page in the website.
In LoginContext.cs properties, marked it as BuildAction = Compile.
You can achieve this behaviour when these classes are located in different projects.
If this is true then you should use full path to the class starting from the project name
ProjectName.stman.LoginContext
try using constructor
namespace stman
{
// Database is a class that handles the sql queries and such
public class LoginContext : Database
{
public LoginContext () : base("Name=LoginContext")
{
}
}
}
From what I read from the App_Code behavior may be different in web site projects and web application. I wonder what kind of project you're working on? One possible solution would be to make this project in web application project, this Link can help you to make this project:
Source

Get ASP.NET assembly from OnInit of custom server control?

I'm trying to build an ASP.NET custom server control which displays version information about the ASP.NET project containing the page on which the server control is rendered.
What is the C# syntax to get the assembly of that ASP.NET project?
That is, given this OnInit override inside the custom server control's code...
protected override void OnInit(EventArgs e) {
System.Reflection.Assembly assembly = Foo();
}
... what goes in Foo()?
EDIT: The custom server control is defined in a Class Library project/assembly which is not the ASP.NET project/assembly.
public Assembly GetPageAssembly()
{
var pageType = Page.GetType();
return Assembly.GetAssembly(pageType.BaseType == null
|| pageType.BaseType == typeof (Page)
? pageType : pageType.BaseType);
}
No matter where the control's implementation is, a separate dll or the current one, it will be instantiated in a Page class in the end and added to its Controls collection. This Page is accessible via the Page method and, based on this, will find the assembly.
For an .aspx file ( actually a couple of them if more ), ASP .Net creates a dll. If the "Inherit" attribute is set, then the generated class will look something like:
public _Default_aspx : Namespace._Default, IHttpHandler {
}
This dll is different than the one compiled by Visual Studio, the result of an "Web Application Project" and I think you are interested more for the latest. This dll has the "_Default: type, that we see in Visual Studio:
public _Default : System.Web.Page
{
}
So why this short story? When this.Page.GetType() is called from the server control, then, if the Inherit attribute is set, the method will return _Default_aspx type, but is useless for you, since you need the assembly created by Visual Studio and not the one generated by ASP .Net from aspx/ascx files. If the page or the control has Inherit attribute set, then GetType() it suffices.
Knowing the type, a simply call to Assembly.GetAssembly method returns the assembly you need.

Categories