0

我试图在 ASP.NET 中创建一个具有泛型类型参数的自定义控件。我已阅读以下文章,这些文章提供了一个起点。

我已经实现了我认为的三个关键要素

  1. 具有 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. 通用基类 (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. 控件生成器 (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
    

Default.aspx页面如下所示:

    <%@ 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>

我创建了一个简单的类MyClass来测试控件:

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

当代码运行时,我在浏览器中收到以下解析错误:

解析器错误消息:基类包含字段“TestId”,但其类型 (ServerControls.MyControl) 与控件类型不兼容 (ServerControls.MyControlBase`2[[TestSite.MyClass, TestSite, Version=1.0.0.0,文化=中性,PublicKeyToken=null],[System.Int32,mscorlib,版本=4.0.0.0,文化=中性,PublicKeyToken=b77a5c561934e089]])

我在上面列出的第二个链接中下载并运行了该项目,并得到了同样的错误。第二篇文章的作者Steven James Gray指出了这个错误并确认此功能在 ASP.NET 4 中不可用。

问题

  1. 在尝试使用泛型类型创建自定义控件时,我是否缺少任何关键点?
  2. 解析错误与情况有何关系

我正在使用以下内容:

  1. Visual Basic 2012 (VB11)
  2. 视觉工作室 2012
  3. 目标框架:.NET Framework 4.5
4

0 回答 0