我在谷歌上搜索了一段时间,也许我没有在搜索正确的术语。我想要一个能够加载/运行其他 Web 应用程序的“外壳”asp.net Web 应用程序(就像 Prism 对 Silverlight xap 文件所做的那样)。但是,除了“子项目”之外,我似乎找不到任何用语,这需要一个人将项目添加到解决方案中。我只是想将 WebApplicationB.dll 放到 Bin 文件夹中,让 ShellWebApplication 加载 dll 并在 iframe 或其他东西中显示默认页面。
如何做到这一点或在哪里可以找到有关如何做到这一点的信息?
更新:悬赏给可以展示代码或向我提供展示如何完成此操作的示例项目的人。希望能够“加载”另一个 asp.net 网站/web 应用程序及其依赖项(dll 或无)并显示加载的 asp.net web 应用程序的 default.aspx 起始页而不改变已经包含 shell 的 Visual Studio 解决方案asp.net 网络应用程序。
最佳答案
这实际上很容易完成;我们做到了。
主要的关键是你的“模块”应该有自己的内容文件夹,或者你需要注意不要在同一位置有完全相同的文件名。
考虑以下人为的示例:
Shell
\default.aspx
\login.aspx
\Images <- images used by shell
\css <- primary CSS files
\Pages\Accounts <- all of the account editing pages here.
Module1
\Module1\Pages <- web pages specific to Module 1
\Module1\Images <- images specific to module 1
\CSS\Module1.css <- Optionally, you can place the Module 1 CSS file into the main CSS directory.
使用此结构,您将能够将两个 Web 应用程序复制到同一目标目录中。由于 .Net 的功能,这将工作得很好,并且两者都将在同一进程空间内执行。
当然,您需要一种方法让 Shell 了解 Module 1。并且您希望能够在没有 Module1 的情况下部署 Shell。这里最好的方法是添加一个包含您需要的接口(interface)定义的程序集项目。您将对此项目的引用添加到 Shell 和模块 1。类似于:
Core
\ObjectModel\MenuOption.cs
\Extension\IAppModule.cs
\Extension\PluginFactory.cs
IAppModule.cs 看起来像这样:
public interface IAppModule {
Collection<MenuOption> GetMenu( );
}
MenuOption.cs 看起来像这样:
public class MenuOption {
public string Href { get; set; } // url the option goes to
public string Title { get; set; } // display name of the menu option
}
PluginFactory.cs 类似于:
public sealed class PluginFactory {
PlugingFactory() { }
public static IAppModule LoadPlugin( string typeName ) {
Type theType = Type.GetType(typeName);
return (IAppModule)Activator.CreateInstance(theType);
}
}
此处 GetMenu 的目的是返回对模块中可用页面的引用集合。
在 Module1 中,您将实现如下接口(interface):
public class AppModule : IAppModule {
public Collection<MenuOption> GetMenu() {
Collection<MenuOption> result = new Collection<MenuOption>();
result.add(new MenuOption() { Href = "~/Module1/Pages/AccountList.aspx", Title="Account List"});
result.add(new MenuOption() { Href = "~/Module1/Pages/NewAccount.aspx", Title="New Account"});
return result;
}
}
因此,此时我们有 2 个 Web 应用程序项目和 1 个程序集项目。 Web 应用程序项目彼此之间一无所知。
下一步是告诉 Shell Module1 存在。我们通过拥有可用模块的数据库表来做到这一点。您可以在 web.config 文件中做同样的事情。最主要的是 shell 项目需要类型名称和对模块 1 的 AppModule 类的引用。例如:“Module1.AppModule, Module1
”
然后,在您的 shell 母版页中,您可以执行以下操作:
protected void LoadMenu() {
// get list of available modules, just assuming mdules is string[]
foreach(String moduleId in moduleIds) {
IAppModule module = PluginFactory.LoadPlugin(moduleId); // now you have a reference to the module
Collection<MenuOption> options = module.GetMenu();
// and now we have all of the menu options for that module...
}
}
为了加分,我们在 shell 项目的根目录中有一个名为“Main.master”的母版页。我们的每个模块在其根目录中也有一个“Main.master”母版页。模块中的那些将构建操作设置为无,并将复制到输出设置为不复制。
母版页是我们实际加载菜单选项的地方。此外,每个模块中的所有其他主控都继承自这个主控。有趣的是,后代母版页不关心父级的实际“类型”,只关心该页面的位置。这意味着您可以从 shell 控制您的主母版页,并让每个模块“继承”,只需不部署它们的整个母版页。
例如:
Shell
/main.master <- includes the basic CSS references, content structure and loads the various menus.
Module1
/main.master <- this file will NEVER be deployed and is only here to aid in testing the module independently of the shell
/Module1/Module1.master <- inherits from main.master, adding other common elements for the module.
由于母版页继承的工作方式,Module1.master 文件通过“~/main.master”引用它的父级。通过不部署模块 main.master 而只是部署 shell 的 main.master,我们获得了很大的灵 active 。
最后,您可以将 shell 项目部署到 IIS 服务器上。稍后您可以将 ModuleX 部署在 shell 项目之上(不需要虚拟目录),它就会正常工作。
关于c# - 如何发现一个 Web 应用程序并将其加载到另一个 Web 应用程序中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9424877/