0

Starting and stopping sites in IIS using NAnt

Posted on 30 August 2010 and tagged with , ,
I have recently need to script starting and stopping sites using NAnt. I know there is a lot of buzz around powershell and rake at the time, but i'm still using NAnt in my deployment script. In IIS 6 there were some vb scripts available to perform actions against the IIS using scripts. These scripts has been more or less been replace with powershell commandlets in IIS 7.x. These commandlets uses the Microsoft.Web.Administration.dll to perform the same actions in a more decent manner. Since i'm still using NAnt, i've added a extensions library on github with 2 tasks. IISSiteTask can start and stop sites on on the the local or remote machine IISSiteStatusTask is used to check the current iis status (stopped, started etc)   Getting started 1. Download the source from github 2. Open the solution in Visual Studio 2010 and compile the solution 3. Copy the JarleF.NAnt.Tasks.dll into your bin folder of your NAnt installation To check a sites current status add the following markup <iissitestatus machine="localhost" sitename="default web site" propertyname="sitestatus" /><echo message="Site status: ${sitestatus}" /> To stop a site add the following markup <iissite machine="localhost" sitename="Default Web Site" action="stop" /> And to start a site add the following markup <iissite machine="localhost" sitename="Default Web Site" action="start" />
1

Using the EPiServer Community API outside IIS

Posted on 11 December 2009 and tagged with , , ,
I have recently come across a scenario where i had  to migrate alot of data into EPiServer Community from a legacy system. Since there is quite of a lot of data that needed to be transfered from one system to another, the ideal solutions for us was to do this by code via a console app The console app exports data from the legacy system and inserts it into EPiServer Community by using the powerful community framework. This is however not as simple as it sounds. Here is a little howto on what you have to do to overcome this challenge. 1. Creating a community/relate site Create a new site using the deployment center. This is the community site i want to import data into. In this example i have installed an relate site into the following directory c:\EPiServer\Sites\RelateDemo\Source\Web. Open the project file in the web folder in Visual Studio. Rename the EPiServer.Templates.RelatePlus to Web. Save the solution in by select the solution project in Visual studio and save it via File -> Save as. Store it in the parent folder of the project (c:\EPiServer\Sites\RelateDemo\Source) 2. Creating the console app Create a new console application by selecting the solution file -> new project -> console application. I called my console app MigrationTool. Set the console application as the startup project. The solution should now look similar to this: Now you must add a bounch of references to the EPiServer Common Framework and THe EPiServer Community Framework. Simple right click the console app project (e.g MigrationTool), then select add reference. Add all assemblies found in the following directories: C:\Program Files (x86)\EPiServer\CommonFramework\2.3.517.36\bin C:\Program Files (x86)\EPiServer\Community\3.2.517.24\bin 3. Reusing the community configuration The goal of the console app is to use the community framework in the same matter as the RelatePlus templates does. This requires however a fair amount of configuration in the console apps app.config file and it would basicly look the same as the web.config of the Web project. Instead of creating a new config file for the console app, it would be better to reuse the copying the existing configuration from our web project. Create a script that copies the config files from the web project by right clicking the the console project and select Properites and then select the Build events tab. Add the following script in the Post-Build events textbox xcopy "$(SolutionDir)web\*.config" "$(TargetDir)" /y /q /s copy $(TargetDir)web.config $(TargetPath).config /y Like this Notice the last line of the script. It creates a file called MigrationTool.exe.config so that the console app can read the community configuration. When you build the console app and click the "don't lie to me"-button you will notice the bin folder will now contain the following files: You can now add some code uses the community framework in the console app. E.g fetching the default admin user via the community api: //Using the community api EPiServer.Common.Security.IUser user = EPiServer.Community.CommunitySystem.CurrentContext.DefaultSecurity.GetUser(1); Console.WriteLine(user.UserName);   Don't be disapointed. It won't run quite yet. 4. Initializing the Community Framework If you try to use any of the methods on the community api now you will get a horrible null reference exception since the community framework is not initialize. To work around this you need to trigger the community api to initialize. Add the following code above the code from the previous section: //Initializing the framework EPiServer.Common.Web.Global.OnBeginRequest(); 5. Mocking the HttpContext The console app will still not work. I digged far and deep into to the community api and i spoted that the api references a lot of HttpContext.Current. The most notable is the CachingHandler class that relies on the HttpContext.Current.Cache object. To work around this you need to mock the HttpContext. Add a reference to the System.Web.dll in the console app project and add the following code above the code from the previous sections  //Mock HttpContext string fileName = "default.aspx"; string url = "http://local.relatedemo.com"; string queryString = null; var sb = new StringBuilder(); var sw = new StringWriter(sb); var request = new HttpRequest(fileName, url, queryString); var response = new HttpResponse(sw); var context = new HttpContext(request, response); HttpContext.Current = context; 6. The Hack: Injecting the community configuration Oh no. Another problem. When running the application now it will throw the following exception: The application relative virtual path '~/' is not allowed here. It turnes out that the EPiServer Common Framework + EPiServer Community Framework assemblies is reading their configuration by using the the System.Web.Configuration.WebConfigurationManager and providing it with a relative path "~" which won't work outside a web server environment. To avoid the configuration being read using the WebConfigurationMananger you need to inject the configuration into the framework classes yourself. Add a reference to the System.configuration.dll and add the following code above the previous code. //Read app config file System.Configuration.Configuration config = null; config = System.Configuration.ConfigurationManager.OpenExeConfiguration(typeof(Program).Assembly.Location); //Inject configuration into the EPiServer Common + EPiServer Community framework Type type = null; FieldInfo field = null; type = typeof(EPiServer.Common.Configuration.EPiServerCommonSection); field = type.BaseType.GetField("m_config", BindingFlags.Static | BindingFlags.NonPublic); field.SetValue(null, config); type = typeof(EPiServer.Community.Configuration.EPiServerCommunitySection); field = type.BaseType.GetField("m_config", BindingFlags.Static | BindingFlags.NonPublic); field.SetValue(null, config); This code reads the configuration from the MigrationTool.exe.config file and injects it into two private static fields deep inside the framework classes using reflection. The EPiServer Common Framework and the EPiServer Common Framework will hence detect the configuration has already been read verifying that the m_config is no longer null and WebConfigurationManager.OpenWebConfiguration("~") is never called :-) 7. The Happy Ending Finally. The code is working and the alias of the username of the admin is printed to the screen:     Here is the complete source code for this examples:   //Read app config file System.Configuration.Configuration config = null; config = System.Configuration.ConfigurationManager.OpenExeConfiguration(typeof(Program).Assembly.Location); //Inject configuration into the EPiServer Common + EPiServer Community Type type = null; FieldInfo field = null; type = typeof(EPiServer.Common.Configuration.EPiServerCommonSection); field = type.BaseType.GetField("m_config", BindingFlags.Static | BindingFlags.NonPublic); field.SetValue(null, config); type = typeof(EPiServer.Community.Configuration.EPiServerCommunitySection); field = type.BaseType.GetField("m_config", BindingFlags.Static | BindingFlags.NonPublic); field.SetValue(null, config); //Mock HttpContext string fileName = "default.aspx"; string url = "http://local.relatedemo.com"; string queryString = null; var sb = new StringBuilder(); var sw = new StringWriter(sb); var request = new HttpRequest(fileName, url, queryString); var response = new HttpResponse(sw); var context = new HttpContext(request, response); HttpContext.Current = context; //Initializing the framework EPiServer.Common.Web.Global.OnBeginRequest(); //Using the community api EPiServer.Common.Security.IUser user = EPiServer.Community.CommunitySystem.CurrentContext.DefaultSecurity.GetUser(1); Console.WriteLine(user.UserName);   Now you can create users (with belonging mypage), forum rooms, topics and threads etc. All inside a external non web application. I hope that this hack is not needed in future releases of the EPiServer Community, but rater add more flexiblity to the framework like using IoC when reading configuration, cach etc so that these small but anoying dependencies can be finally be removed. :-)
1

EPiServer: Creating sites in IIS based on the web.config

Posted on 28 February 2009 and tagged with , ,
EPiServer CMS 5 R2 SP1 is finally here. Happy times :-) The EPiServer developers have really made a quality product. However there are a few features missing in the new Deployment Center tool. One feature I'm missing is the ability to create IIS sites based on the web.config file. This becomes apparent when dealing with larger enterprise solution. [More]

Disclaimer

© Copyright 2009, Jarle Friestad. The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.

Widget Twitter not found.

Root element is missing.X

Month List