TL;DR
Is it possible to replace the Inherits="..." of a UserControl using a class defined in a code-block, rather than the class in the compiled code-behind?
I have an ASP.NET web application that I quickly need to patch, but I am only allowed to update the .aspx and .ascx files... it is not possible for me to re-compile and release .dll files (due to the change management processes the client puts on us).
In the application I have a UserControl that is set to Inherit from the code-behind class for the file... but there is a bug in that class.
What I want to do is re-create the entire class within a <script runat="server"></script> block in the .ascx file with the appropriate bugfix.
I've tried the following, but I get...
Could not load type 'MyCtrlStatic'.
<%# Control Language="vb" AutoEventWireup="false" Inherits="MyCtrlStatic" %>
<script runat="server">
Public Class MyCtrlStatic
Inherits UserControl
Public Function DisplayValue() As String
Return "Hello World"
End Function
End Class
</script>
<div><%=DisplayValue()%></div>
The control in question is using a lot of different properties and methods from the code-behind class, and the above is a massive simplification of the issue.
Is this possible to achieve? Otherwise I'm looking at re-building and going through an entire change management procedure.
The answer was staring me in the face, and I couldn't see it until just a few minutes ago...
Instead of trying to declare a new Class and inherit from it, the answer is to inherit directly from UserControl and then have the code directly in the code-block.
<%# Control Language="vb" AutoEventWireup="false" Inherits="UserControl" %>
<script runat="server">
Public Function DisplayValue() As String
Return "Hello World"
End Function
</script>
<div><%=DisplayValue()%></div>
In addition the above, I also had to add a few Import command, such as...
<%# Import Namespace="System.Collections.Generic" %>
But now I have a patched .ascx file that doesn't require the rebuilding of the DLL to work
Related
I want to add two aspx pages for single aspx.cs file. Is it possible? I need to do this directly.
namespace WebApplication1
{
public partial class PROJECT2 : System.Web.UI.Page
{
}
}
PROJECT2 ASPX.CS should be used for two aspx pages.
Not truly supported by Microsoft
I discussed this with Microsoft and here is what I got from them.
After further investigation, here are the results. Due to the manner in which Intellisense works, we cannot support Intellisense for scenarios involving a shared code behind on the aspx.cs files. There are two different approaches that one can take to deal with this scenario. The option supported in VS is using either AppCode or UserControll for the common code elements and then calling those methods to achieve a common code base. The second option involves using the CodeBehind in the manner that you are currently using it (without Intellisense), and assuming that the code is correct with respect to both design pages, the code should compile correctly since it is an ASP.NET supported scenario. Thank you for your feedback.
So here what that means
Intellisense will not work with both the pages, but only with one page
your code will compile only if both the controls are on both the pages!
This really is against the idea of having a shared codeBehind file. My scenario will most likely be two slight different pages which uses same code behind. But for Microsoft, two slightly different pages, can not use the same codebehind file
Ideal Scenarios should be
Intellisense should pick controls in both the pages
Code should compile if the the control that is accessed is present in either of the two pages.
So here it is the solution that perfectly suited my needs (thanks again ps2goat for the hint).
My basic structure of two pages was:
[namespace A]
Page.aspx
Page.aspx.cs
Page.aspx.designer.cs
and
[namespace B]
Page.aspx
Page.aspx.cs
Page.aspx.designer.cs
(assume i do have far more than 2 pages)
I did need to remove the .cs and .designer.cs files while being able to refer to server controls declared in the .aspx page.
This could not be possible with standard inheriting from base classes, nor using master pages: they work well, but are completely unaware of the children ASPX server controls.
So, I created a generic class file
[namespace COMMON]
Page.cs
In this file, I copied the content of both ".cs" partial class and ".designer.cs" partial class (obviously taking care of changing namespace to the new one) of either of the original namespaces (they were identical in code).
In page.aspx file, codebehind mapping was updated from "Page.aspx.cs" and "A.Page" namespace to "Page.cs" and "Common.Page" namespace.
So, files changed from these:
[Page.aspx] (one instance for each namespace)
<%# Page Title="Page" Language="C#" MasterPageFile="~/Page.Master" AutoEventWireup="true" CodeBehind="Page.aspx.cs" Inherits="Project.A.Page" %>
<asp:Content ID="ContentB" ContentPlaceHolderID="cBody" runat="server">
<asp:TextBox ID="txbTest" runat="server" MaxLength="75"></asp:TextBox>
</asp:Content>
[Page.aspx.cs] (one instance for each namespace)
namespace Project.A
{
public partial class Page: BasePage
{
protected void Page_Load(object sender, EventArgs e)
{
this.txbTest.Text = "Hello";
}
}
}
[Page.aspx.designer.cs] (auto-generated, one instance for each namespace)
namespace Project.A {
public partial class Page{
protected global::System.Web.UI.WebControls.TextBox txbTest;
}
}
To these:
[Page.aspx] (one instance for each namespace)
<%# Page Title="Page" Language="C#" MasterPageFile="~/Page.Master" AutoEventWireup="true" CodeBehind="Page.cs" Inherits="Project.COMMON.Page" %>
<asp:Content ID="ContentB" ContentPlaceHolderID="cBody" runat="server">
<asp:TextBox ID="txbTest" runat="server" MaxLength="75"></asp:TextBox>
</asp:Content>
[Page.cs] (one SINGULAR instance, made by the content of old .cs and .designer files)
namespace Project.COMMON
{
public partial class Page: BasePage
{
protected void Page_Load(object sender, EventArgs e)
{
this.txbTest.Text = "Hello";
}
}
public partial class Page{
protected global::System.Web.UI.WebControls.TextBox txbTest;
}
}
Then I deleted each instance of page's .cs and .designer.cs files, leaving a structure as I needed, like:
~/A/Page.aspx
~/B/Page.aspx
~/COMMON/Page.cs
And it works like a charm!
Taken from Can ASPX pages share code behind file?
I've just started to create my website (from scratch with empty project) and I'm getting some errors however I'm really confused!
Default.aspx
<%# Page Language="C#" CodeFile="Default.aspx.cs" Inherits="MonoLightTech.WebSite.Default" %>
<html>
<head>
<meta charset="utf-8" />
<title>MonoLight Technology</title>
</head>
<body>
<%= MonoLightTech.WebSite.Style.TestField %>
</body>
</html>
Style.cs (BuildAction: Compile)
namespace MonoLightTech.WebSite
{
public static class Style
{
public static string TestField = "MonoLight Technology";
}
}
Solution Hierarchy
Visual Studio: I also noticed, VS can see Style class and TestField member
I'm a C# programmer already (desktop) and I'm sure, there is no problem with member access. I also ReOpened the project, Cleaned the solution and ReBuilt the project. What's wrong? Should be simple I think :)
EDIT: Here is the solution project with all sources including all assets >>
Finally I see what's wrong. I've changed back Output path from .\ to bin\ and it works. I really don't know why but this is the solution for me. Maybe someone can explain this later for us (I hope). And I think, starting from scratch not always the best way :)
Try to include following line at the top of the page:
<%# Import Namespace="MonoLightTech.WebSite" %>
I can't tell if there are namespace issues with the page, but because you're namespacing Style.cs to the "MonoLightTech.Website" namespace explicitly, it may be that your Default.aspx only exists in the "MonoLightTech" namespace and so you'd need to drop an include statement at the top of the Default.aspx page like:
<%# Import Namespace="MonoLightTech.Website" %>
In order to have access to the field in the Style class.
I have inherited someone elses code and was wondering if there is any reason I would need to keep both of these in the page directives? I have tried it removing classname and things still seem to work. Just wondering.
<%# Control Language="C#" AutoEventWireup="true" CodeFile="YourProgram.ascx.cs" Inherits="program.YourProgram" ClassName="program.YourProgram" %>
If your ascx file doesn't contain any code, the ClassName attribute is not needed, see http://blogs.msdn.com/b/thirusrinivasan/archive/2008/07/16/classname-vs-inherits.aspx.
However, Inherits and ClassName do different things. ClassName will set the name of the class generated out of the ascx file, while Inherit will make the generated class inherit from the class in the code behind:
http://msdn.microsoft.com/en-us/library/vstudio/d19c0t4b(v=vs.100).aspx
I'm trying to construct a custom control for ASP.NET
I started by creating a Web Application in VS2010 and creating a new .ascx page. The page is called "TestBox" and it's just a single TextBox control with "This is a test" as the text.
I built the project and then included the DLL in another website in order to make sure I would be able to move controls. Based on a tutorial I found here I added the following line of code to the top of the page:
<%# Register TagPrefix="TestControl" Namespace="TestControl" Assembly="TestControl" %>
Then I added this to the page itself:
<TestControl:TestBox ID="TestBox1" runat="server" />
The code compiles and the page loads without throwing up any errors, but when it loads it's completely blank. By introducing a deliberate runtime error, I determined that the TextBox is definitely being loaded, but the control itself still isn't showing up.
Am I missing something?
Code for the TestControl:
<%# Control Language="C#" AutoEventWireup="true" CodeBehind="TestBox.ascx.cs" Inherits="TestControl.TestBox" %>
<asp:TextBox ID="TextBox1" runat="server" ontextchanged="TextBox1_TextChanged">This is a test</asp:TextBox>
I haven't touched the Designer code or the .cs code in any way.
EDIT: Figured it out. I had declared a namespace for the .CS file but not the .ASPX file itself.
The answer was that I had to add a namespace to the ASPX file itself and not just the underlying code file. I forgot to add Class="TestControl.TestBox" to the page declaration.
after weeks of having this issue I finally decided to ask for a solution to the following problem:
In the .aspx page you can set
<%# MasterType VirtualPath="~/Mastername.master" %>
This results in an auto generated property in the .aspx.designer
public new Mastername Master {
get {
return ((Masternamee)(base.Master));
}
}
Works perfectly fine. But if I do changes in the .aspx file, the property will be new auto generated and it looks like the following:
public new NAMESPACE1.Mastername Master {
get {
return ((NAMESPACE1.Mastername)(base.Master));
}
}
Compiling will not be possible afterwards, because the class for the MasterPage cannot be resolved at the given namespace.
The masterpage has NAMESPACE1 as namespace.
Every contentpage has the same NAMESPACE1.
The autogenerated property tries to look for the masterpage class in NAMESPACE1.NAMESPACE1 which will fail, due to it does not exist. Of course I can remove the first NAMESPACE1. to make the app compilable again, but it just sucks to do this nearly every time I make changes in the .aspx file.
Is there a way to avoid this problem? The only way I can think of, is to ignore the auto generated property and make a explicit cast everytime I want have access to the masterpage.
Edit: I'm using Visual Studio 2008 Professional SP1.
For some reason the designer believes that the master page is defined in namespace NAMESPACE1, so look at the master page definition (and code behind) to check its namespace has not been modified (possibly accidentally).
If there is nothing obvious, a search in all files (*.cs, *.aspx, *.master, ...) for NAMESPACE1 may be needed.
(This is where using a VCS would help --- you could check the history of changes.)
Actually it's more a designer "feature". ;-)
The Master name used in your designer file will be pulled from your .Master file's Inherits property. So change how you qualify the Inherits attribute, and that will change the class name used when the designer file is created.
I found a solution that works. I won't use the autogenerated property in the designerfile. I'll write my own wrapper property that I do implement in every contentpage.
I had this same problem when I added <%# MasterType VirtualPath="~/TestMaster.Master" %> to my aspx page in SOURCE view. For some reason, the page never created correctly and kept giving me invalid namespace errors until I actually changed to DESIGN view and resized a control and finally the error went away. Somewhere it was using some cached data (even a Build/Clean Solution didn't clear it out) and until the designer recreates the page, it generates that error.
Change
<%# MasterType VirtualPath="~/Mastername.master" %>
to
<%# MasterType TypeName="Mastername" %>
this will work perfectly