问题
I am creating Web User Controls
via code (my C# code write-out markup, code-behind and designer files to disk on a callback). The controls are created all fine. I can add them to my web-project and put them on a page.
When I try to load the control using LoadControl(path)
it says:
Unable to load type 'MyNameSpace.UseControlClass'
which is because control is not yet compiled.
But my requirement is to load controls dynamically without recompiling the solution.
How can I compile the user control only when I create the control files? As this seems to be the only way out.
EDIT:- What my guess is that as the file is not compiled yet it is not allowed to be loaded by runtime. I have tried to compile the code file using CodeDom
compiler. Like:
var filePath = Server.MapPath(path);
var provider = CSharpCodeProvider.CreateProvider("C#");
var opts = new CompilerParameters(new[] { "mscorlib.dll", "System.Web.dll",
"Telerik.Web.Design.dll", "Telerik.Web.UI.dll",
"Telerik.Web.UI.Skins.dll", "MyCurrentDll.dll"});
opts.GenerateExecutable = false;
opts.GenerateInMemory = true;
var cr = provider.CompileAssemblyFromFile(opts, new string[] { filePath+".cs" });
But it complains about cannot find metadata file Telerik.Web.Design.dll
etc. I don't want to hardcode the telerik path as it might be different in hosted system (though it is in the bin
of current web app). Also MyCurrentDll.dll
is the dll of the file from which I'm compiling the code file. How can I resolve this?
My idea is to compile the code file create a dll
dynamically and copy it to web application's bin
directory. It might solve the problem I originally stated.
EDIT 2:- After hit and trial I am able to compile the code file dynamically and generate the dll
. Even after generating dll and placing it into bin
of my application I am not able to load user control using virtual path
. I have tried the following approach:
var asm = Assembly.Load("ddlPath");
var t = asm.GetType(fullTypeName);//NameSpace.Class
var ctrl = LoadControl(t,null);
The ctrl is loaded after this. I assign its Id
property and add it to an asp.net Panel
control. But it is not visible after the postback :(
Now I either have to make somehow the dynamically compiled dll's types available to the runtime (appdomain, maybe) so that when I load control using virtual path it is properly loaded and I don't get HtmlParseException
or figure out why loading control form Type
is not showing up.
PS:- I have loaded a Label
control using Type
and it is working properly.
回答1:
In the end I was able to resolve the problem. Following is the strategy I adopted:
- Create text files containing structure of
CodeBehind
,Markup
andDesigner
code - Read the information as to what fields to create.
- Put markup for controls needed in string builders.
- put some other related information into more string builders
- Write files
After this I created the dll
using CodeDome
compiler. The main problem faced during compilation, as described in Edit
part of question, was not finding referenced assemblies, which was resolved by putting path of bin
directory's path along with dll file name like:
Server.MapPath("~/bin")+"\\Telerik.Web.dll"
etc.
Next problem outlined in EDIT2
was bit simpler. There was rather moronic. There was some problem in another user control embedded in dynamically generated user control.
Even after this i was not able to load the control into the page from where I compiled the code. This was resolved when I loaded the control in another page. The runtime was able to resolve the type from dynamically compiled dll
.
回答2:
hmm.. have you considered using App_Code folder for this purpose?
Contains source code for shared classes and business objects (for example, ..cs, and .vb files) that you want to compile as part of your application. In a dynamically compiled Web site project, ASP.NET compiles the code in the App_Code folder on the initial request to your application. Items in this folder are then recompiled when any changes are detected.
来源:https://stackoverflow.com/questions/10223752/loading-ascx-control-created-dynamically-via-code