AddWebPart 不能添加动态加载的自定义控件吗?
做了一个自定义控件。强名称。动态加载添加到页面上是可以的。
Assembly asembly = Assembly.LoadFile(@"C:\Inetpub\wwwroot\WebApplication2\WebApplication2\UILib\MyWebControls.dll");
object obj = asembly.CreateInstance("MyWebControls.TestText");
con = LoadControl(obj.GetType(), null);
con.ID = "ddd";
this.Panel1.Controls.Add(con);
但是,如果添加到 WebPartManager里就会出问题:
Assembly asembly = Assembly.LoadFile(@"C:\Inetpub\wwwroot\WebApplication2\WebApplication2\UILib\MyWebControls.dll");
object obj = asembly.CreateInstance("MyWebControls.TestText");
con = LoadControl(obj.GetType(), null);
con.ID = "ddd";
this.WebPartManager1.AddWebPart( this.WebPartManager1.CreateWebPart(con), this.WebPartZone1, 0);
报错:
不能添加 MyWebControls.TestText 类型的控件。类型必须能够被 BuildManager.GetType(string typeName)加载。
请问这是怎么回事,怎么解决?肯请解答。多谢。
源码下载地址: http://ldhyyiqi.cn/upload/动态添加自定义用户控件到%20WebPart.rar
用Reflector 5.0 分析类 WebPartMananger 如下:(只贴主要代码)
![](/Images/OutliningIndicators/ContractedBlock.gif)
Reflector code.
1
WebPartManager :
2![](/Images/OutliningIndicators/None.gif)
3
public WebPart AddWebPart(WebPart webPart, WebPartZoneBase zone, int zoneIndex)
4![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
5
return this.AddDynamicWebPartToZone(webPart, zone, zoneIndex);
6
}
7
8![](/Images/OutliningIndicators/None.gif)
9
WebPartManager :
10
private WebPart AddDynamicWebPartToZone(WebPart webPart, WebPartZoneBase zone, int zoneIndex)
11![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
12
WebPart part = this.CopyWebPart(webPart); //这是出错部分.
13
this.Internals.SetIsStatic(part, false);
14
this.Internals.SetIsShared(part, this.Personalization.Scope == PersonalizationScope.Shared);
15
this.AddWebPartToZone(part, zone, zoneIndex);
16
this.Internals.AddWebPart(part);
17
this.Personalization.CopyPersonalizationState(webPart, part);
18
this.OnWebPartAdded(new WebPartEventArgs(part));
19
return part;
20
}
21
22
23![](/Images/OutliningIndicators/None.gif)
24
WebPartManager
25![](/Images/OutliningIndicators/None.gif)
26
protected virtual WebPart CopyWebPart(WebPart webPart)
27![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
28
WebPart part;
29
GenericWebPart part2 = webPart as GenericWebPart;
30
if (part2 != null)
31![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
32
Control childControl = part2.ChildControl;
33
this.VerifyType(childControl); //这是出错部分.
34
Type type = childControl.GetType();
35
Control control = (Control) this.Internals.CreateObjectFromType(type);
36
control.ID = this.CreateDynamicWebPartID(type);
37
part = this.CreateWebPart(control);
38
}
39
else
40![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
41
this.VerifyType(webPart);
42
part = (WebPart) this.Internals.CreateObjectFromType(webPart.GetType());
43
}
44
part.ID = this.CreateDynamicWebPartID(webPart.GetType());
45
return part;
46
}
47
48![](/Images/OutliningIndicators/None.gif)
49
WebPartManager
50
private void VerifyType(Control control)
51![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
52
if (!(control is UserControl))
53![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
54
}
55
return;
56
Type type = control.GetType();
57
string typeName = WebPartUtil.SerializeType(type);
58
if (WebPartUtil.DeserializeType(typeName, false) != type) //这是出错部分
59![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
60![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
throw new InvalidOperationException(SR.GetString("WebPartManager_CantAddControlType", new object[]
{ typeName }));
61
}
62
goto Label_003F;
63
}
64
65
66![](/Images/OutliningIndicators/None.gif)
67
WebPartUtil:
68
internal static Type DeserializeType(string typeName, bool throwOnError)
69![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
70
return BuildManager.GetType(typeName, throwOnError); //这是出错部分
71
}
72
73
74![](/Images/OutliningIndicators/None.gif)
75
BuildManager:
76
public static Type GetType(string typeName, bool throwOnError)
77![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
78
return GetType(typeName, throwOnError, false); //这是出错部分
79
}
80
81
82![](/Images/OutliningIndicators/None.gif)
83
BuildManager:
84
public static Type GetType(string typeName, bool throwOnError, bool ignoreCase)
85![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
86
Type t = null;
87
if (Util.TypeNameContainsAssembly(typeName))
88![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
89
t = Type.GetType(typeName, throwOnError, ignoreCase);
90
if (t != null)
91![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
92
return t;
93
}
94
}
95
if (!InitializeBuildManager())
96![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
97
return Type.GetType(typeName, throwOnError, ignoreCase);
98
}
99
try
100![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
101
t = typeof(BuildManager).Assembly.GetType(typeName, false, ignoreCase); //这是出错部分
102
}
103
catch (ArgumentException exception)
104![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
105![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
throw new HttpException(SR.GetString("Invalid_type", new object[]
{ typeName }), exception);
106
}
107
if (t == null)
108![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
109
_theBuildManager.EnsureTopLevelFilesCompiled();
110
t = Util.GetTypeFromAssemblies(TheBuildManager.TopLevelReferencedAssemblies, typeName, ignoreCase);
111
if (t != null)
112![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
113
return t;
114
}
115
AssemblyCollection assembliesForAppLevel = CompilationUtil.GetAssembliesForAppLevel();
116
if (assembliesForAppLevel != null)
117![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
118
Type type2 = CompilationUtil.GetTypeFromAssemblies(assembliesForAppLevel, typeName, ignoreCase);
119
if (type2 != null)
120![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
121
if ((t != null) && (type2 != t))
122![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
123![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
throw new HttpException(SR.GetString("Ambiguous_type", new object[]
{ typeName, Util.GetAssemblySafePathFromType(t), Util.GetAssemblySafePathFromType(type2) }));
124
}
125
t = type2;
126
}
127
}
128
if ((t == null) && throwOnError)
129![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
130![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
throw new HttpException(SR.GetString("Invalid_type", new object[]
{ typeName }));
131
}
132
}
133
return t;
134
}
135![](/Images/OutliningIndicators/None.gif)
136
137![](/Images/OutliningIndicators/None.gif)
分析到这里,就有很多问题了.
typeof(BuildManager).Assembly.GetType(typeName, false, ignoreCase);
这个函数是报错的.单纯的拿这个函数来讲, 我想在指定的程序集里创建对象,但这个函数没有指定程序集.所以只能说,走到这一步,是不对的.
对此,问题似乎有些眉目,如何让 AddWebPart 函数走正确的路.去正确创建.
顺带着的问题是. typeof(BuildManager).Assembly.GetType 这个函数如何使用.
暂时分析到这里.欢迎有相关经验的朋友提出宝贵意见。
问题解决。创建方法如下:
1.把DLL放到 BIN 文件夹下。
2.把生成的代码改为:
Type t = BuildManager.GetType("MyWebControls.TestText", true);
object obj = t.Assembly.CreateInstance("MyWebControls.TestText");
WebControl con = (WebControl)obj;
con.ID = "ddd";
Response.Write(t.FullName);
GenericWebPart gweb = this.WebPartManager1.CreateWebPart(con) ;
Response.Write( gweb.IsStatic ) ;
this.WebPartManager1.AddWebPart(gweb, this.WebPartZone1, 0);
现在,还不清楚是怎么回事。呵。让我给撞上了。哪位朋友给解释一下,BuildManager.GetType 的寻找路径方式?多谢。
如果我想把 DLL 文件放到自定义的文件夹下,该怎么办呢?
(需设置 AppDomainSetup.PrivateBinPath 。)