question

MarkDavich-2464 avatar image
0 Votes"
MarkDavich-2464 asked FeiXue-MSFT commented

How can I create a custom server control that inherits from a generic class

I am attempting to create a custom control in ASP.NET that has generic type parameters.
I have read the following articles which provided a starting point.

I have implemented what I feel to be the three crucial elements
1. Non-Generic Class with a ControlBuilder (MyControl.vb)

 Imports System.Web.UI
    
 <ControlBuilder(GetType(MyControlBaseBuilder))>
 Public Class MyControl
     Inherits MyControlBase(Of Object, Object)
  
     Public Property ModelName As String
 End Class

2. Generic Base Class (MyControlBase.vb)

 Imports System.Web.UI
 Imports System.Web.UI.WebControls
    
 Public Class MyControlBase(Of TModel, TValue)
     Inherits CompositeControl
    
     Public Property FieldName As String
     Public Property Model As TModel
    
     Public Property Value As TValue
         Get
             Return Model.GetType().GetProperty(FieldName).GetValue(Model)
         End Get
         Set(value As TValue)
             Model.GetType().GetProperty(FieldName).SetValue(Model, value)
         End Set
     End Property
 End Class

3. Control Builder (MyControlBaseBuilder.vb)

 Imports System.Web.UI
    
 Public Class MyControlBaseBuilder
     Inherits ControlBuilder
    
     Public Overrides Sub Init(parser As TemplateParser, parentBuilder As ControlBuilder, type As Type, tagName As String, id As String, attribs As IDictionary)
         Dim modelName As String = attribs("ModelName")
         Dim fieldName As String = attribs("FieldName")
    
         Dim modelType = System.Type.GetType(modelName)
         Dim model = Activator.CreateInstance(modelType)
         Dim valueType = model.GetType().GetProperty(fieldName).PropertyType
    
         Dim concreteType = GetType(MyControlBase(Of ,)).MakeGenericType(New Type() {modelType, valueType})
    
         MyBase.Init(parser, parentBuilder, concreteType, tagName, id, attribs)
     End Sub
 End Class

The Default.aspx page looks like this:

 <%@ Page Title="Home Page" Language="VB" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="Default.aspx.vb" Inherits="TestSite._Default" %>
 <%@ Register Assembly="ServerControls" Namespace="ServerControls" TagPrefix="cc1" %>
    
 <asp:Content runat="server" ID="BodyContent" ContentPlaceHolderID="MainContent">
     <cc1:MyControl runat="server" ID="TestId" ModelName="TestSite.MyClass, TestSite" FieldName="Age" />
 </asp:Content>

and I created a simple class MyClass to test the control:

 Public Class MyClass
     Public Property Age As Integer
     Public Property Name As String
 End Class

When the code runs I get the following Parse Error in the browser:

Parser Error Message: The base class includes the field 'TestId', but
its type (ServerControls.MyControl) is not compatible with the type of
control (ServerControls.MyControlBase`2[[TestSite.MyClass, TestSite,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null],[System.Int32,
mscorlib, Version=4.0.0.0, Culture=neutral,
PublicKeyToken=b77a5c561934e089]])

I downloaded and ran the project in the second link, listed above, and get the same error.
Steven James Gray, the author of the second article has this to say about the error:

This is a known issue with ASP .NET 4.0. What Microsoft have done is rework some of the generics
handling code and type resolution in the ASP .NET codebehind generation classes.
The side effect is that my tutorial, and every other generics enabling tutorial for ASP .NET
is effectively broken at the moment.

Here's the Microsoft connect link regarding this bug - I'd raised it 16/07/2010 but still not action:

http://connect.microsoft.com/VisualStudio/feedback/details/575898/asp-net-controlbuilder-type-substitution-not-respected-in-vs-designer-file[^]

Questions
1. Since the article was written in 2009, things have changed and Steven's solution no longer works. Can the same functionality be achieved using other methods?
2. How does the Parse Error relate to the situation
3. Are there any modern tutorials that outline how to create generic server controls?

I am using the following:
1. Visual Basic 2012 (VB11)
2. Visual Studio 2012
3. Target Framework: .NET Framework 4.5

NOTE: I have asked this question on stackoverflow here


dotnet-visual-basicdotnet-aspnet-generaldotnet-aspnet-webpages
· 4
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

I have tried the code sample from the second link with Visual Studio 2019(Version 16.11.1) and it works well for me. Can you try to test it with and let me whether it works for you?

0 Votes 0 ·

@FeiXue-MSFT, I have tested it and get the error described above. The original author explains that the issue occurs in .NET 4.0. What version of .NET are you using?

0 Votes 0 ·
Show more comments

0 Answers