I am doing automation in my company. We are a C# workshop.
Currently I am working on automated build. NANT is flow control tool. While NANT is not actively developed (last binary released on June 2012 and github repo is not active), MSBuild is better. Therefore, I prefer MSBuild but retiring NANT is still questionable - what is the cost?
I have come up with some pros and cons, but I know collective intelligence is better. Thanks for your help!
Update:
I have read the question, but the second answer rises a concern for me. On build machine there are multiple .NET frameworks, will it be troublesome?
MSBuild
Pros:
Commercial support
Community is growing
Intergrated with VS and TFS
Keep pace with .Net
Cons:
Rewrite current script
Not familiar by people
NANT
Pros:
Already in use
Familiar by people
Cons:
Not updated for a long time (since 2012)
Community is not active
Lack of new .Net support
We wrote FlubuCore (rewrite of Flubu). It's an open source C# library for building projects and executing deployment scripts using C# code.
Main advantages of flubu that I see are:
.Net Core support.
Easy to learn and to use because you write build script entirely in C#.
Fluent interface and intelisense.
Quite a lot of built in tasks (compile, running tests, managing iis, creating deploy package, publishing nuget packages, executing powershell scripts...)
Write your own custom c# code in script and execute it..
Run any external program or command in script with RunProgramTask.
Reference any .net library or c# source code file in buildscript. Now also available option to reference nuget package in build script.
Write tests, debug your build script..
Use flubu tasks in any other .net application.
Web api is available for flubu. Useful for automated deployments remotely.
Write your own flubu tasks and extend flubu fluent interface with them.
You can find flubu on nuget:
Search for FlubuCore.Runner if u need it for .net project
Search for dotnet-flubu if u need it for.net core project
Example of how flubu is used in .net:
protected override void ConfigureBuildProperties(IBuildPropertiesContext context) {
context.Properties.Set(BuildProps.NUnitConsolePath,
# "packages\NUnit.ConsoleRunner.3.6.0\tools\nunit3-console.exe");
context.Properties.Set(BuildProps.ProductId, "FlubuExample");
context.Properties.Set(BuildProps.ProductName, "FlubuExample");
context.Properties.Set(BuildProps.SolutionFileName, "FlubuExample.sln");
context.Properties.Set(BuildProps.BuildConfiguration, "Release");
}
protected override void ConfigureTargets(ITaskContext session) {
var loadSolution = session.CreateTarget("load.solution")
.SetAsHidden()
.AddTask(x => x.LoadSolutionTask());
var updateVersion = session.CreateTarget("update.version")
.DependsOn(loadSolution)
.SetAsHidden()
.Do(TargetFetchBuildVersion);
session.CreateTarget("generate.commonassinfo")
.SetDescription("Generates common assembly info")
.DependsOn(updateVersion)
.TaskExtensions().GenerateCommonAssemblyInfo()
var compile = session.CreateTarget("compile")
.SetDescription("Compiles the solution.")
.AddTask(x => x.CompileSolutionTask())
.DependsOn("generate.commonassinfo");
var unitTest = session.CreateTarget("unit.tests")
.SetDescription("Runs unit tests")
.DependsOn(loadSolution)
.AddTask(x => x.NUnitTaskForNunitV3("FlubuExample.Tests"));
session.CreateTarget("abc").AddTask(x => x.RunProgramTask(# "packages\LibZ.Tool\1.2.0\tools\libz.exe"));
session.CreateTarget("Rebuild")
.SetDescription("Rebuilds the solution.")
.SetAsDefault()
.DependsOn(compile, unitTest);
}
//// Some custom code
public static void TargetFetchBuildVersion(ITaskContext context) {
var version = context.Tasks().FetchBuildVersionFromFileTask().Execute(context);
int svnRevisionNumber = 0; //in real scenario you would fetch revision number from subversion.
int buildNumber = 0; // in real scenario you would fetch build version from build server.
version = new Version(version.Major, version.Minor, buildNumber, svnRevisionNumber);
context.Properties.Set(BuildProps.BuildVersion, version);
}
Example of how flubu is used in .net core
public class MyBuildScript : DefaultBuildScript
{
protected override void ConfigureBuildProperties(IBuildPropertiesContext context)
{
context.Properties.Set(BuildProps.CompanyName, "Flubu");
context.Properties.Set(BuildProps.CompanyCopyright, "Copyright (C) 2010-2016 Flubu");
context.Properties.Set(BuildProps.ProductId, "FlubuExample");
context.Properties.Set(BuildProps.ProductName, "FlubuExample");
context.Properties.Set(BuildProps.SolutionFileName, "FlubuExample.sln");
context.Properties.Set(BuildProps.BuildConfiguration, "Release");
}
protected override void ConfigureTargets(ITaskContext context)
{
var buildVersion = context.CreateTarget("buildVersion")
.SetAsHidden()
.SetDescription("Fetches flubu version from FlubuExample.ProjectVersion.txt file.")
.AddTask(x => x.FetchBuildVersionFromFileTask());
var compile = context
.CreateTarget("compile")
.SetDescription("Compiles the VS solution and sets version to FlubuExample.csproj")
.AddCoreTask(x => x.UpdateNetCoreVersionTask("FlubuExample/FlubuExample.csproj"))
.AddCoreTask(x => x.Restore())
.AddCoreTask(x => x.Build())
.DependsOn(buildVersion);
var package = context
.CreateTarget("Package")
.CoreTaskExtensions()
.DotnetPublish("FlubuExample")
.CreateZipPackageFromProjects("FlubuExample", "netstandard2.0", "FlubuExample")
.BackToTarget();
//// Can be used instead of CreateZipPackageFromProject. See MVC_NET4.61 project for full example of PackageTask
//// context.CreateTarget("Package2").AddTask(x =>
x.PackageTask("FlubuExample"));
var test = context.CreateTarget("test")
.AddCoreTaskAsync(x => x.Test().Project("FlubuExample.Tests"))
.AddCoreTaskAsync(x => x.Test().Project("FlubuExample.Tests2"));
context.CreateTarget("Rebuild")
.SetAsDefault()
.DependsOn(compile, test, package);
}
}
Detailed presentation and documentation can be found here:
https://github.com/flubu-core/flubu.core
You can find full examples here:
https://github.com/flubu-core/examples
Thanks for all answers. We have decided to use Cake since we are a C# workshop.
There is a property nant.settings.currentframework which is used to set target framework in case you have multiple .net framework
<property name="nant.settings.currentframework" value="net-2.0" />
As per .92 build:
nant.settings.currentframework The current target framework, eg. 'net-1.0'.
nant.settings.currentframework.description Deprecated. Description of the current target framework.
nant.settings.currentframework.frameworkdirectory Deprecated. The framework directory of the current target framework.
nant.settings.currentframework.sdkdirectory Deprecated. The framework SDK directory of the current target framework.
nant.settings.currentframework.frameworkassemblydirectory Deprecated. The framework assembly directory of the current target framework.
nant.settings.currentframework.runtimeengine Deprecated. The runtime engine of the current target framework if used eg. mono.exe.
Related
I have created a .net core console application using TopShelf. But I got an error when running the application using docker (alpine-linux).
Configuration Result:
[Success] Name MyApp
[Success] DisplayName MyApp
[Success] Description My Application
[Success] ServiceName MyApp
Topshelf v4.1.0.177, .NET Framework v4.0.30319.42000
Topshelf.Runtime.Windows.WindowsHostEnvironment Error: 0 : Unable to get parent process (ignored), System.DllNotFoundException: Unable to load shared library 'kernel32.dll' or one of its dependencies. In order to help diagnose loading problems, consider setting the LD_DEBUG environment variable: Error loading shared library libkernel32.dll: No such file or directory
at Topshelf.Runtime.Windows.Kernel32.CreateToolhelp32Snapshot(UInt32 dwFlags, UInt32 th32ProcessID)
at Topshelf.Runtime.Windows.WindowsHostEnvironment.GetParent(Process child)
Topshelf.HostFactory Error: 0 : The service terminated abnormally, System.PlatformNotSupportedException: ServiceController enables manipulating and accessing Windows services and it is not applicable for other operating systems.
at System.ServiceProcess.ServiceController.GetServices()
at Topshelf.Runtime.Windows.WindowsHostEnvironment.IsServiceListed(String serviceName)
at Topshelf.Hosts.ConsoleRunHost.Run()
at Topshelf.HostFactory.Run(Action`1 configureCallback)
How to solve this issue? I need to run my console application as a windows service
The Topshelf documentation is pretty specific:
To work with Topshelf you will need to be running on a Windows operating system. The developers of Topshelf regulary test on Windows 7 and Windows Server 2008RC2. Though it should still work on Windows Server 2003, as long as .Net 3.5 sp1 is installed.
The good news is that writing Linux daemons is easier than Windows Services - all they have to be is basically a console application where you control the main loop.
If I got your problem statement correctly, you want to be able to run one service both in Windows and in Docker. In this case it seems the easiest way will be to examine your OS environment on start up with something like System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform()
and either defer your main work to Topshelf or run it Linux-style. For the example below I installed Microsoft.Extensions.Hosting package and opted for implementing an IHostedService (which Topshelf can conveniently reuse)
public class YourHostedService : IHostedService, IDisposable
{
private int executionCount = 0;
private Timer _timer;
public YourHostedService()
{
}
public Task StartAsync(CancellationToken stoppingToken)
{
_timer = new Timer(DoWork, null, TimeSpan.Zero,
TimeSpan.FromSeconds(5));
return Task.CompletedTask;
}
private void DoWork(object state)
{
executionCount++;// this gets called every 5 seconds
}
public Task StopAsync(CancellationToken stoppingToken)
{
_timer?.Change(Timeout.Infinite, 0);
return Task.CompletedTask;
}
public void Dispose() => _timer?.Dispose();
}
public class Program
{
public static async Task Main(string[] args)
{
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
var rc = HostFactory.Run(x =>
{
var token = CancellationToken.None;
x.Service<YourHostedService>(s =>
{
s.ConstructUsing(name => new YourHostedService());
s.WhenStarted(tc => tc.StartAsync(token));
s.WhenStopped(tc => tc.StopAsync(token));
});
x.RunAsLocalSystem();
x.SetDescription("TopShelf Host");
x.SetDisplayName("YourHostedService");
x.SetServiceName("YourHostedService");
});
}
else
{
await Host.CreateDefaultBuilder(args)
.ConfigureServices(builder =>
{
builder.AddHostedService<YourHostedService>();
})
.RunConsoleAsync();
}
}
}
More inspiration can be drawn from here.
UPD So it seems your particular case can also be solved by running arbitrary (well, in this case your) program as Windows service.
In this case you've got some options that don't involve programming but rather config writing:
The Microsoft's own tool SrvAny that's been part of NT Resource Kit: you basically install it as a dummy service and edit the registry setting to point to your .exe
A 3rd party tool SrvStart: this one's relatively easy to pick up as well, and config is similar to the above
So your requirement is to run a dotnet core (which version?) application as a windows service.
TopShelf might not be the right tool for this, as it supports .NET Framework 4.0 or Mono, not dotnet core.
Since you want to run a windows service, it does not make any sense to publish your app as a Linux Docker image! Use sc create and sc start to register and start your published executable instead.
Topshelf is not a good choice for .NET Core because .Net Core has powerful facilities for build Windows Service. Furthermore, TopShelf is only supporting Windows.
See Examples:
https://medium.com/#tocalai/create-windows-service-using-net-core-console-application-dc2f278bbe42
https://codeburst.io/create-a-windows-service-app-in-net-core-3-0-5ecb29fb5ad0
This is the same question as this but for the recent version of application insights 2.2.1
Since updating to the 2.2 version the debug output is filled with AI data even if it is disabled the way it used to be done.
Previously AI was enabled in startup and I could do something like this:
services.AddApplicationInsightsTelemetry(options =>
{
options.EnableDebugLogger = false;
options.InstrumentationKey = new ConnectionStringGenerator().GetAITelemetryKey();
});
The new method of adding application insights, per the new VS templates, is to add it in Program.cs like this:
public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.UseApplicationInsights(connectionStringGenerator.GetAITelemetryKey())
.UseSerilog()
.Build();
In this case there is no construction that takes any options and if I remove the 'UseApplicationInsights' and revert to the original method it makes no difference. Either way I get the output debug window filled wit AI logs.
In fact, even if there is no method to load AI (i.e. I remove both the 'UseApplicationInsights' and 'AddApplicationInsightsTelemetry' I get the logs.
Thanks for any help.
You can opt out of telemetry (for debug, for example) by setting a DOTNET_CLI_TELEMETRY_OPTOUT environment variable to 1.
Visual Studio is lighting up Application Insights even if you have no code to enable it. You can create an environment variable, ASPNETCORE_PREVENTHOSTINGSTARTUP = True, to prevent Visual Studio from lighting up Application Insights.
How to do this?
Right click the project in VS, Select Properties.In Debug options add environment variable as shown in below screenshot.
I've included custom code activities in TFS2012 and below.
In the "new world" changes in TFS2015, (non-work-flow driven)......I cannot figure out how to add a custom activity.
Now do I integrate the below into a TFS 2015 build?
using System.Activities;
using Microsoft.TeamFoundation.Build.Client;
using Microsoft.TeamFoundation.Build.Workflow.Activities;
namespace MyCompany.TFS.CodeCoverageLibrary
{
[BuildExtension(HostEnvironmentOption.All)]
[BuildActivity(HostEnvironmentOption.All)]
public sealed class SimpleCodeActivity : CodeActivity<bool>
{
protected override bool Execute(CodeActivityContext context)
{
context.TrackBuildMessage(string.Format("ActivityInstanceId='{0}', WorkflowInstanceId='{1}'", context.ActivityInstanceId, context.WorkflowInstanceId));
return true;
}
}
}
You don't. The new build system is a complete, ground-up rewrite. XAML build activities won't work in the new build system, although they will continue to work in the XAML build system.
The new task system is based on JSON descriptor files with activities written as PowerShell (for Windows) or Node JS (for cross-platform). You can see examples of the task library on GitHub: https://github.com/Microsoft/vsts-tasks
I'm interested in using Steve Sanderson’s MvcIntegrationTestFramework or a very similar alternative with ASP.NET MVC 3 Beta.
Currently when compiling MvcIntegrationTestFramework against MVC 3 Beta I get the following error due to changes in MVC:
Error 6
'System.Web.Mvc.ActionDescriptor.GetFilters()' is obsolete: '"Please call System.Web.Mvc.FilterProviders.Providers.GetFilters() now."' \MvcIntegrationTestFramework\Interception\InterceptionFilterActionDescriptor.cs Line 18
Questions
Can anybody provide the MvcIntegrationTestFramework working for ASP.NET MVC 3 Beta?
--- and / or ---
Are there similar alternatives you would recommend?
EDIT #1: Note I have e-mailed Steve the creator of MvcIntegrationTestFramework, also hoping for some feedback there.
EDIT #2 & #3: I have received a message from Steve. Quoted for your reference:
I haven't needed to use that project with MVC 3, so sorry, I don't have an updated version of it. As far as I'm aware it should be possible to update it to work on MVC 3, but you'd need to figure that out perhaps by inspecting the MVC 3 source code to notice any changes in how actions, filters, etc are invoked now. If you do update it, and if you decide to adopt it as an ongoing project (e.g., putting it on Github or similar), let me know and I'll post a link to it! (Thanks Steve!)
EDIT #4: Honestly had a quick stab at using System.Web.Mvc.FilterProviders.Providers.GetFilters() didn't get anywhere fast and simply adding the [Obsolete] found that there was an error in the internals of the MVC requests. Anybody else had a dabble?
EDIT #5: Please comment if you are using an alternative Integration Test Framework with MVC 3.
Have a look at my fork:
https://github.com/JonCanning/MvcIntegrationTestFramework/
I realize this is not the answer you're looking for but Selenium or Watin may be of use to you as an alternative to the Integration Test Framework.
Selenium will let you record tests as nUnit code so you can integrate with your existing test projects etc. Then your test can validate the DOM similarly to the Integration Test Framework. The advantage is Selenium tests can be executed with various different browsers.
Key caveat is that Selenium needs your app to be deployed on a web server, not sure if that's a show stopper for you.
I thought I would share my experiences with using MvcIntegrationTestFramework in an ASP.NET MVC 4 project. In particular, the ASP.NET MVC 4 project was a Web Role for a Windows Azure Cloud Service.
Although the example project from Jon Canning's fork worked for me (although I did change the System.Web.Mvc assembly from 3.0.0.0 to 4.0.0.0, which required a bunch of editing in the web.config file to get the tests to run and pass), I got an error whenever I tried to run the same tests against an Azure ASP.NET MVC 4 Web Role project. The error was:
System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation.
The inner exception was:
System.InvalidOperationException: This method cannot be called during the application's pre-start initialization phase.
I started wondering how an Azure Web Role project based on ASP.NET MVC 4 was different to a normal ASP.NET MVC 4 project, and how such a difference would cause this error. I did a bit of searching on the web but didn't come across anybody trying to do the same thing that I was doing. Soon enough I managed to realise that it was to do with the Microsoft.WindowsAzure.Diagnostics.DiagnosticMonitorTraceListener. Part of the role of this class seems to be to ensure that the web role is running in a hosted service or the Development Fabric (you'll see a message to this effect if you switch the startup project from the cloud service project to the web role project inside a cloud service solution, and then try to debug).
The solution? I removed the corresponding listener from the Web.config file of my Web Role project:
<configuration>
...
<system.diagnostics>
<trace>
<listeners>
<!--Remove this next 'add' element-->
<add type="Microsoft.WindowsAzure.Diagnostics.DiagnosticMonitorTraceListener, Microsoft.WindowsAzure.Diagnostics, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
name="AzureDiagnostics"> <filter type="" /> </add>
</listeners>
</trace>
</system.diagnostics>
...
</configuration>
I was then able to run integration tests as normal against my Web Role project. I did, however, add the listener to the Web.Debug.config and Web.Release.config transformation files so that everything was still the same for normal deploying and debugging.
Maybe that will help somebody looking to use the MvcIntegrationTestFramework for Azure development.
EDIT
I just realised that this solution might be a bit of a 'hack' because it might not let you do integration testing on application code that relates to Azure components (e.g. the special Azure caching mechanisms perhaps). That said, I haven't come across any issues to do with this yet, although I also haven't really written that many integration tests yet either...
I used Jon Canning's updated version (https://github.com/JonCanning/MvcIntegrationTestFramework/) and it solved my problem very well for controller methods that only accept value types and strings, but did not work for those that accepted classes.
It turns out there was an issue with the code for the updated MvcIntegrationTestFramework.
I figured out how to fix it, but don't know where else to post the solution, so here it is:
A simple sample to show how it works is:
[TestMethod]
public void Account_LogOn_Post_Succeeds()
{
string loginUrl = "/Account/LogOn";
appHost.Start(browsingSession =>
{
var formData = new RouteValueDictionary
{
{ "UserName", "myusername" },
{ "Password", "mypassword" },
{ "RememberMe", "true"},
{ "returnUrl", "/myreturnurl"},
};
RequestResult loginResult = browsingSession.Post(loginUrl, formData);
// Add your test assertions here.
});
}
The call to browsingSession.Post would ultimately cause the NameValueCollectionConversions.ConvertFromRouteValueDictionary(object anonymous) method to be called, and the code for that was:
public static class NameValueCollectionConversions
{
public static NameValueCollection ConvertFromObject(object anonymous)
{
var nvc = new NameValueCollection();
var dict = new RouteValueDictionary(anonymous); // ** Problem 1
foreach (var kvp in dict)
{
if (kvp.Value == null)
{
throw new NullReferenceException(kvp.Key);
}
if (kvp.Value.GetType().Name.Contains("Anonymous"))
{
var prefix = kvp.Key + ".";
foreach (var innerkvp in new RouteValueDictionary(kvp.Value))
{
nvc.Add(prefix + innerkvp.Key, innerkvp.Value.ToString());
}
}
else
{
nvc.Add(kvp.Key, kvp.Value.ToString()); // ** Problem2
}
}
return nvc;
}
Then there was two problems:
The call to new RouteValueDictionary(anonymous) would cause the "new" RouteValueDictionary to be created, but instead of 4 keys, there are only three, one of which was an array of 4 items.
When it hits this line: nvc.Add(kvp.Key, kvp.Value.ToString(), the kvp.Value is an array, and the ToString() gives:
"System.Collections.Generic.Dictionary'2+ValueCollection[System.String,System.Object]"
The fix (to my specific issue) was to change the code as follows:
var dict = anonymous as RouteValueDictionary; // creates it properly
if (null == dict)
{
dict = new RouteValueDictionary(anonymous);
}
After I made this change, then my model class would properly bind, and all would be well.
Using ASP.NET MVC 1.0 (current) I create a new default ASP.NET MVC project using Visual Studio 2008 on an x64 machine (Server 2008) and accept all the defaults and build and run it. Apart from having to set the System.Web.* assemblies as "Copy Local" it runs and brings up the default web app. When I try and run the unit tests on this project I get:
Unit Test Adapter threw exception: Unable to load one or more of the requested types. Retrieve the LoaderExceptions property for more information..
Now if I repeat the same exercise using VS2008 on an x86 machine (Server 2003) then all 27 default unit tests run fine. (Also I don't need to mark the System.Web.* assemblies as "Copy Local")
Ideas for resolving the exception?
More Info:
After trying some of the solutions suggested I started commenting out parts of the boilerplate test code that is generated with a new project. As such, I believe that the error is being generated by the inclusion of one of the following classes:
public class MockIdentity : IIdentity
{
public string AuthenticationType
{
get
{
return "MockAuthentication";
}
}
public bool IsAuthenticated
{
get
{
return true;
}
}
public string Name
{
get
{
return "someUser";
}
}
}
public class MockPrincipal : IPrincipal
{
IIdentity _identity;
public IIdentity Identity
{
get
{
if (_identity == null)
{
_identity = new MockIdentity();
}
return _identity;
}
}
public bool IsInRole(string role)
{
return false;
}
}
public class MockMembershipUser : MembershipUser
{
public override bool ChangePassword(string oldPassword, string newPassword)
{
return newPassword.Equals("newPass");
}
}
public class MockHttpContext : HttpContextBase
{
private IPrincipal _user;
public override IPrincipal User
{
get
{
if (_user == null)
{
_user = new MockPrincipal();
}
return _user;
}
set
{
_user = value;
}
}
}
First, have you tried it in Release configuration? Have you done a clean on your solution?
Have you tried constructing your test project? Take out the source files for your tests, delete the project from your solution and add a new test project that references the MVC app. Then re-add the test source files.
Edit
Are the classes and interfaces that you are using and implementing in scope from your tests?
Edit
Is it referencing the x64 not the x86 dlls?
Do you have VS 2008 SP1 and .NET 3.5 SP1 installed in your Win2k8 box? By default VS 2008 installed 3.5 framework, but NOT SP1. Make sure you have both the framework SP1 and VS 2008 SP1 installed.
Did you try building your project as x86 project (Project properties ->Build ->Platform target) on x64 machine?
Also, not sure about your unit testing toolkit, but NUnit, for example, can run as tests as either x86 or x64 (on x64 machine). If one of your assemblies accesses some 32-bit code (e.g. COM object), trying to run them under x64 will result in "Unable to load one or more of the requested types" error.
I'm not sure about the subtleties of what's going on with the x64 verus x86, but using custom identity/principals can cause some interesting little glitches to happen, especially if using cassini (the built-in vshost webserver - which I think is what you end up using by running local unit tests within VS). I ran into this issue before, and rather than detailing it here, I'll post a link to some good info. Again, I'm not sure if this is related to your problem (my not being an MVC guru), but take a read through this. Food for thought:
http://www.lhotka.net/weblog/UpdateOnMyStrugglesWithTheASPNETDevelopmentServer.aspx
EDIT: so ultimately, this may be an issue of serialization failure, even if this particular edge case is not relevant. Have you tried marking your mocked iidentity/iprincpal objects as [serializable]? Remember that visual studio is a 32bit application; perhaps testing it on IIS (if not cassini) with a 64bit application pool is causing a context switch somewhere which causes the mock identities (if they get assigned as a thread's identity) to get marshalled across a boundary like that - the lack of a [serializable] attribute will probably cause a TypeLoadException.
Does it still throw if you set IIS to use a 32bit application pool (on your 64bit server)?
-Oisin
I'm wondering if the more significant difference is 2k8 vs 2k3 than 64 vs 32bit. Did you spawn Visual Studio as Administrator? An assembly might be missing due to the Virtual Store of windows 2k8. If this is a development desktop running 2k8 you might want to consider disabling the Virtual Store, it's in you policy labeled as "User Account Control: Virtualize file and registry write failures to per-user locations"
I notice some of the types (specifically IIdentity and IPrincipal) you are implementing are not located within a System.Web.* assembly.
Have you tried marking the System.Security.Principal assembly as "Copy Local"?
This reminded me of an old blog post I once read. Perhaps you can use the same technique to debug the cause of the error:
http://www.agileprogrammer.com/oneagilecoder/archive/2007/11/17.aspx