The installer was interrupted before [Web App] could be installed

by 25. December 2008 00:53

CASK is starting to move to the front burner with the birth of http://www.amarillo.us.com/; in the new year Global Webnet, LLC will be looking to provide the Amarillo Business Community with a higher visibility in the Internet Community.   Mainly because of the last 4 bookings my wife received (she is a professional Videographer/Photographer) they all said they found her on the Intefrnet.  

My attempts to create a new release for CASK were greeted with the error "The installer was interrupted..." as shown in Figure B.


Figure A.

My first reaction/assumption was it was because of my new Vista Ultimate x64 development environment so I set the TargetPlatform to x64 (see above) with no luck - I was still getting the following error:


Figure B.

Googling this error resulted in a lot of different applications having the same problem with users asking the same question; this was turning into quite the adventure....

With no solutions being offered for my early Googling efforts I was very happy to see the following solution - unfortunately when I attempted the aspnet_regiis -i command I was greeted with a response that said IIS was not installed - as you can see it is installed and works....


Figure C. 

The only thing I could think of was perhaps it had to do with IIS Compatibility mode - so I went into Control Panel, Program and Features and added IIS 6.0 Management Compatibility.


Figure D. 

Unfortunately, this did not make aspnet_regiis any happier - it still reported that IIS was not installed.   I suspect this has something to do with this .NET 2.0.50727 command no longer being valid with IIS 7, .NET 3.5 w/SP1.

HOWEVER!!!!  My Web installation problem went away!   I am now able to install my new CASK installation application without issue :)

My assumption would have to be that IIS 6.0 Compatibility Manager is required for Vista Ultimate x64, .NET 3.5 w/SP1 Web Installations.   Whether this is the case for your issue???  We can only hope.

CASK - MEF / Unity - Chicken before the egg....

by 23. December 2008 10:59

Problem Statement:  The Community Starter Kit, while very powerful and dynamic, is not extensible due to it's complexity; although CASK "is" extensible in the technical sense the CSK has not taken off with the C# Community because the learning curve is very steep.    

Vision Statement: Use MEF to permit programmers to easily create modules that users can upload, configure and use (isolating them from the complexity of the system).   Currently I have successfully plugged in the MEFContrib's MEFContrib.Library.Web project.  


Code review request - email comments to Bill@global-webnet.com or post them HERE in the MEF forum.   The current design will permit MEF to be used to load MEFModules so that they are available when the page attempts to dynamically instantiate them.   Unity will be used for dependency injection, event aggregation, etc.   In summary: MEF usage will have to be limited to loading external modules (uploaded modules) and Unity will be used for internal use. 
 

CASK HIGH-LEVEL OVERVIEW (within the context of this story)

The Community (Advanced) Starter Kit dynamically instantiates classes (see first arrow in figure B) and is a data driven application; there is only one page (Community_Default.aspx) that serves up all pages for the entire site.  

Currently there is an IModule interface that allows modules to be programmatically added via the Admin | Modules section (the Calendar and Update module are currently functional).  The problem is these modules have to be compiled into the application otherwise there are issues that MEF is here to eliminate.  

The "dynamic instantiation" of the applicable class requires that the module/assembly be loaded in memory prior to the CreateInstance statement - MEF modules must be loaded prior to the ASP.NET Page_Init().    Currently this is accomplished in the IHttpModule.Page_Init() method.

This forced me to modify the MEFContrib project so that MEF objects were composed prior to the pages Page_Init().   Since all controls are not added until after Page_Init(), reference second arrow in Figure B, this means those dynamically modules cannot have MEF Imports/Exports. 

Modified UnityHttpModule.cs from MEFContrib project: 

using System;

using System.Web;

using System.Web.UI;

using System.Collections.Generic;

using System.ComponentModel.Composition;

using Microsoft.Practices.Unity;

 

namespace MEFContrib.Library.Web.Unity {

public class UnityHttpModule : IHttpModule {

 

private HttpApplication context;

private IUnityContainer Container {

    get { return HttpContext.Current

        .Application.GetContainer(); }

}

 

/// <summary>

/// Ensure any MEF Imports/Exports are processed/available

/// for Page_Init

/// </summary>

/// <param name="sender"></param>

/// <param name="e"></param>

private void page_Init(object sender, EventArgs e)

{

    CompositionContainer compositionContainer =

        ((CompositionContainer)Container

            .Resolve<ICompositionService>());

 

    compositionContainer.Compose();

}

 

/// <summary>

/// Build up each control in the page's control tree - done during

/// post init to ensure dynamically loaded controls get processed

/// </summary>

/// <param name="sender"></param>

/// <param name="e"></param>

private void OnPageInitComplete(object sender, EventArgs e)

{

    Page page = (Page)sender;

    foreach (Control c in GetControlTree(page))

        Container.BuildUp(c.GetType(), c);

}

 

/// <summary>

/// Get the controls in the page's control tree excluding the page

/// itself

/// </summary>

/// <param name="root"></param>

/// <returns></returns>

private IEnumerable<Control> GetControlTree(Control root)

{

    foreach (Control child in root.Controls)

    {

        yield return child;

        foreach (Control c in GetControlTree(child))

            yield return c;

    }

}

 

public void Init(HttpApplication context)

{

    this.context = context;

    context.PreRequestHandlerExecute +=

        OnPreRequestHandlerExecute;

}

 

public void Dispose()

{

    context.PreRequestHandlerExecute -=

        OnPreRequestHandlerExecute;

}

 

private void OnPreRequestHandlerExecute(

    object sender, EventArgs e)

{

 

    IHttpHandler handler = HttpContext.Current.Handler;

    HttpContext.Current.Application.GetContainer()

        .BuildUp(handler.GetType(), handler);

 

    Page page = HttpContext.Current.Handler as Page;

    if (page != null)

    {

        page.InitComplete += OnPageInitComplete;

        page.Init += new EventHandler(page_Init);

    }

}

 

 

}

}

 

 

Below we see that when we hit the breakpoint in Page_Init (figure b) that we have both a reference to the IUnityContainer and MEFModule - breakpoint watch window follows: 


Figure A. 


Figure B.

CASK full source available HERE Changeset 45207

Modified MEFHttpApplication.cs from MEFContrib.Library.Web 

using System;

using System.ComponentModel.Composition;

using System.Web;

using MEFContrib.Library.Web.Unity;

using Microsoft.Practices.Unity;

 

namespace MEFContrib.Library.Web.UI {

public class MEFHttpApplication : HttpApplication {

 

protected IUnityContainer Container

{

    get { return HttpContext.Current

            .Application.GetContainer(); }

}

 

protected void Application_Start(object sender, EventArgs e)

{

    Container

        .AddNewExtension<MEFContainerExtension>();

 

    var catalog =

        new DirectoryPartCatalog("bin", "*.dll", false);

 

    Container

        .RegisterInstance<ComposablePartCatalog>(catalog);

 

    ApplicationStart(sender, e);

}

 

protected void Application_End(object sender, EventArgs e)

{

    ApplicationEnd(sender, e);

    Container.Dispose();

}

 

protected void Application_BeginRequest(

    object sender, EventArgs e)

{

    var catalog = Container.Resolve<ComposablePartCatalog>();

    CompositionContainer compositionContainer =

        new CompositionContainer(catalog);

    Container.RegisterInstance<ICompositionService>(

        compositionContainer);

 

    ApplicationBeginRequest(sender, e);

}

 

protected void Application_EndRequest(

    object sender, EventArgs e)

{

    ApplicationEndRequest(sender, e);

}

 

protected void Application_Error(

    object sender, EventArgs e)

{

    ApplicationError(sender, e);

}

 

protected virtual void ApplicationStart(

    object sender, EventArgs e) { }

protected virtual void ApplicationEnd(

    object sender, EventArgs e) { }

protected virtual void ApplicationBeginRequest(

    object sender, EventArgs e) { }

protected virtual void ApplicationEndRequest(

    object sender, EventArgs e) { }

protected virtual void ApplicationError(

    object sender, EventArgs e) { }

}

 

}

 

Tags: ,

MEF

TypeMock - Stub for CASK application

by 25. September 2008 13:13

The CASK application will rely heavily on TypeMock as TDD moves forward.  This could cause a problem for folks who don't use TypeMock and download the source code - it won't compile. 

I've created a TypeMock "stub" that I will update as the test get more advanced; currently the stub will permit the CASK application to compile without error.   To simplify matters for those, like myself, who will be using TypeMock, I will place all affected Unit Test in a TypeMock.Tests folder - this way we can easily remove the reference from the stub and assign it to the actual TypeMock application.

CASK - Overriding default user controls - Changing User Registration / Profile screens

by 22. September 2008 10:19

The CASK Registration form is the same one used back when the Community Starter Kit was written in .NET 1.1; a wee bit outdated and not up with the times, i.e, won't have MySpace, Facebook or Twitter entries.

If you attempted to remove or modify the existing controls you would be greeted with something like the following error:

With the recent changes made you can now delete un-used textbox controls; they are no longer tightly coupled to the baseclass code.   Each textbox in the default registration screen is also tightly coupled to a database entry.   My recommendation is to reuse existing database fields and simply change what is shown to the user, i.e., I use the Occupation and Location fields for "Student Name" and "Relation" fields.

Important note:  Do not change the Master user controls in the Communities\Common\Themes\Default folder.  Instead copy and paste the controls you want to override (replace) in the applicable Theme folder.  By default you do not have to have any controls in your theme, it will use the defaults.  In the case above I modified numerous controls to include the user registration and profile controls.

 

Tags:

TypeMock - Unit test for ASP.NET class utilities

by 22. September 2008 08:29

For our CASK application I am creating a User Import module; I have to import a list of names from an old .NET 1.1 Newsletter application (xml file) into CASK so my client can use it's Newsletter capabilities with existing users.  A user import module (reusable) seemed to be the way to go.

Although a simple utility, I have made a commitment to do TDD from now on so a lot of infrastructure has to be put in place to support it; e.g., the simple process below has to be supported from Unit Test:

The HttpContextBase class takes on the responsibility of ensuring that there is an HttpContext.Current instance; it takes care of this responsibility in it's constructor:


Note: I moved the PhysicalPath line path below line 38 (so it is always set) 

The HttpContext.Current.Server object is a different story - it won't allow me to instantiate a HttpServerUtility object; it is inaccessible.   For this we'll rely on TypeMock; I chose it primarily because it supports SharePoint sealed classes and they have graciously offered us (the open source community) a free licence to use it with our projects.  

Below I configure TypeMock so that when a request for Server.MapPath("App_data") is made that it will return the MockFolderPath; I'll be using this as a location to place the <user>.XML file uploaded via the ASP FileUpload control.

[TestClass]
public class FileUploadUtilFixture :
TestBase
{

[TestMethod]
public void
HttpContext_CanGetContextForUnitTest()
{
    // The TestBase:HttpContextBase constructor will

    // create a HttpContext.Current if it is null
    HttpContext context = HttpContext.Current;
    Assert.IsNotNull(context,
"HttpContextBase should create HttpContext"
);
    Assert.IsNotNull(PhysicalPath);

    // Dynamically generate our MockFolderPath using the

    // TestBase:HttpContextBase.PhysicalPath property (the
    // baseclass used by FileUploadUtil).
    MockFolderPath = PhysicalPath.Replace("default.aspx", "App_Data"
);

    // Instantiate our file Utility class

    FileUploadUtil fileUploadUtil = new
FileUploadUtil();

    // When MapPath("App_Data") is requested supply our

    // MockFolderPath (public static string in TestBase)
    using
(RecordExpectations recorder = RecorderManager.StartRecording())
    {
        HttpContext.Current.Server.MapPath("App_Data"
);
        recorder.Return(MockFolderPath);
    }

    // Use the fileUploadUtil to retrieve our data path

    string
app_dataPath = fileUploadUtil.GetFileFolder();

    // Assert that all is well

    Assert.AreEqual(app_dataPath, MockFolderPath);
    Assert.AreEqual(MockFolderPath, fileUploadUtil.FileFolder);

    MockManager.Verify();
}

Full source code available HERE Change Set: 40436

CASK - Finding and making controls Designer friendly

by 13. September 2008 22:59

Reference: http://www.CodePlex.com/CaskDotNet open source project.

The Community Starter Kit 1.1 (.NET 1.1) was/is a very powerful application - it allows you to setup, configure and maintain a website dynamically within minutes.  To start a new website (community) I simply register a new domain and point it to my server.  When the domain becomes active the CASK will see it doesn't exist and walk you through a wizard to create it.  After that you select your site template and create your pages as shown in the Flash videos in the above referenced link.

The problem with .NET 1.1 version was that it was difficult to find things; everything was under one namespace, all code was on the website and the design time experience was not a pleasant one.   Over the last couple of years I have upgraded the CSK to .NET 2.0, moved all source code out of the website into a CASKDotNetLib assembly and updated all of the controls so that it's ASP tag, e.g., "sections" referenced it's location in the StarterKit/Communities folder as shown below:

I'm preparing a tutorial on how to create a new site (template) from scratch.  It's actually very simple but becomes difficult if you can't see the controls to reference them.  For example, above I just finished fixing "TopicMenu", you can now see it and can reference to drag/drop or remove it.  I now have to do the MultiLevelSectionMenu and the UserLogin controls.

For both controls I only have to add four lines of code (two for each class)

The end results is that I now can see my user controls.  With CASK you can design your layout and then simply drop the controls in the respective areas and the rest will be handled by the dynamic nature of the system (you can maintain and update your system from the CASK admin area - online)

 

Tags:

CASK - Auto update module fires on error

by 24. August 2008 07:19

On May 19th Alex57 wrote the following in this CASK discussion thread

Table - Community_NamedPages

ASPNET.StarterKit.Communities.Login - ASPNET.StarterKit.Communities.Users.Login
ASPNET.StarterKit.Communities.Logout
....
Now that I'm blowing the dust off of the CASK source code I see the problem.

In the first release of CASK there was an annoying coding issue that made things real difficult to find - everything had the same namespace ASPNET.StarterKit.Communities.   It was a MAJOR undertaking to refactor namespaces so that it reflected the folder the class code was located in; almost every code file and user control was touched in the process.  When all was done and said another problem remained - there are tables that store namespaces.
 
This problem was resolved with an "auto update on error" process.   One forgotten about until I ran the following Click-Once application to install a new CASKDB database on my system: http://www.global-webnet.net/CSK/CSKInstall.htm;  when the following error occurs the factory processes it and runs the applicable code to fix the error:

The following process is executed:

public class CASKV2_2_0_0 : ICommand, IHandlesException

{

    private List<NamedPageStruct> namedPage = new List<NamedPageStruct>();

    private string connectionString = string.Empty;

 

    /// <summary>

    /// Flags this class as an Exception handler - if an exception occurs

    /// while loading the page the CommunityDefault.aspx.cs will instantiate

    /// the UpgradeModuleClass and execute this process

    /// </summary>

    public bool IsHandlingException  { get { return true; }  }

 

    /// <summary>

    /// Executed by the UpgradeController class.

    /// </summary>

    /// <param name="sender">Process that initiated the event</param>

    /// <param name="e"></param>

    public void Execute(object sender, EventArgs e)

    {

        // Cast back to ModuleUtilEventArgs

        ModuleUtilEventArgs muea = e as ModuleUtilEventArgs;

 

        if (sender is Exception)

        {

            Exception ex = sender as Exception;

            if (!ex.Message.ToLower().Contains("could not load type"))

                return;

 

            muea.Message = ex.Message;   

        }

 

 

        // Store the connection string for class use

        connectionString = muea.ConnectionString;

 

        // Instantiate our sql connection

        SQLUtil sql = new SQLUtil(connectionString);

        sql.OnExecuteReader += new

            EventHandler<DataEventArgs>(ReaderHandler);

 

        // Pull all current named pages

        sql.SqlExec("Select * from Community_NamedPages");

 

        // ReadHandler will have processed the data and all records

        // will be loaded into the "namedPage" collection.  We

        // Need to find each record and update its

        NameFieldWithContents("Login", "ASPNET.StarterKit.Communities.Users.Login", muea);

        NameFieldWithContents("Logout", "ASPNET.StarterKit.Communities.Users.Logout", muea);

        NameFieldWithContents("Register", "ASPNET.StarterKit.Communities.Users.Register", muea);

        NameFieldWithContents("ShowProfile", "ASPNET.StarterKit.Communities.Users.ShowProfile", muea);

        NameFieldWithContents("EditProfile", "ASPNET.StarterKit.Communities.Users.EditProfile", muea);

        NameFieldWithContents("Password Reminder", "ASPNET.StarterKit.Communities.Users.PasswordReminder", muea);

        NameFieldWithContents("Search", "ASPNET.StarterKit.Communities.Search.Search", muea);

        NameFieldWithContents("Delete Content Page", "ASPNET.StarterKit.Communities.ContentPages.DeleteContentPage", muea);

        NameFieldWithContents("Move Content Page", "ASPNET.StarterKit.Communities.ContentPages.MoveContentPage", muea);

        NameFieldWithContents("Add Comment", "ASPNET.StarterKit.Communities.Comments.AddComment", muea);

        NameFieldWithContents("Topic", "ASPNET.StarterKit.Communities.Topics.Topic", muea);

        NameFieldWithContents("Message", "ASPNET.StarterKit.Communities.Message.Message", muea);

 

        muea.Message = "<b>UPDATED - try process again</b>";

 

    }

Which results in the following output

The tables are updated with the proper namespaces and the program no longer crashes.

So this error will happen if you installed the original release and have downloaded the latest source code and attempt to run the application (since the latest source code expects the namespaces to be correct).  

If you are not running the release version of CASK, i.e., it has been modified, it is possible the error signature will not be the same and the code update won't fire - you'll know this has happened because you won't see the above results.   In this case I need to be contacted so we can support the error signature being provided so that your process will update correctly.

 

Tags:

CASK - release moving to the front burner because of SDMS

by 24. August 2008 05:34

The Community Starter Kit was a popular open source Community Site for .NET 1.1 (reference links on http://www.CodePlex.com/CASKDotNet).  There were numerous issues, particularly with Images not displaying if IIS wasn't configured correctly that plagued the community for years.   When .NET 2.0 beta was released I attempted to join a team, any team, that was involved with CSK so we could fix known issues and upgrade it to support .NET 2.0.   Maintaining the forum was a full-time job and we lost many developers through the frustrations of not being able to make it work out of the box - I wanted to see this change...

Efforts failed to create a team so I was forced to lonewolf it; I fixed known issues and upgraded it to .NET 2.0 (beta at the time).  When CodePlex opened up I created the Community Advanced Starter Kit; I added "Advanced" because "starter" can be misleading; I was lost coming out of the gate because it used many advanced features of ASP.NET 2.0 (such as HttpModule).  

Shortly after joing CodePlex CSharpEd joined the team and he did magic with the Admin styles (rewrote admin management), added RSS feed support and created an installation wizard (to name a few).    CSharpEd and I had different visions (of equal value) for the CSK so we came to a mutual agreement that we should have our own projects; CSharpEd has http://www.CodePlex.com/DotNetCommunities where I have http://www.CodePlex.com/CASKDotNet.  

With the Solution Development Management System (SDMS) on the front burner the CASK system (as of this writing) starts creeping towards the front burner because the SDMS requires a Web Interface; an interface that will be comprised of Microsoft Office SharePoint Server (MOSS) 2007.   The limitations with MOSS 2007, i.e., 2000 records per list, no support for transactions and an inability to handle complex structures, requires programming to an external database.  MOSS 2007 also comes with a price tag that is not compatible with an open source project.  It will be a "core requirement" that the SDMS takes advantage of SharePoint (for those that have it).  For those that don't I need to provide a means to use it without SharePoint - enter stage left CASK.

As I study SharePoint and learn of it's strengths and limitations I'm seeing similiarities between it and the CASK.   The goal now is to create an interface that can be shared by both CASK and MOSS 2007 to manage sites and lists.   The CASK Database will serve as a respository for those custom requirements that can't be handled by MOSS 2007 because of it's limitations.

Within this context, preparing CASK for release becomes a higher priority - it is moving towards the front burner...

Tags: ,

Notice

Blog videos and references to CodePlex projects are no longer valid