Orchard: Association references unmapped class: System.String

After making some changes in one of my modules, I started getting the following error whenever I opened Orchard CMS in a browser:

Server Error in ‘/orchard’ Application.


Association references unmapped class: System.String

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: NHibernate.MappingException: Association references unmapped class: System.String

Source Error:

An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.

Stack Trace:

[MappingException: Association references unmapped class: System.String]

NHibernate.Cfg.XmlHbmBinding.CollectionBinder.BindCollectionSecondPass(ICollectionPropertiesMapping collectionMapping, Collection model, IDictionary`2 persistentClasses, IDictionary`2 inheritedMetas) in c:\Users\sebros\Documents\My Projects\nhibernate-core\src\NHibernate\Cfg\XmlHbmBinding\CollectionBinder.cs:741
NHibernate.Cfg.XmlHbmBinding.<>c__DisplayClass13.<AddCollectionSecondPass>b__12(IDictionary`2 persistentClasses) in c:\Users\sebros\Documents\My Projects\nhibernate-core\src\NHibernate\Cfg\XmlHbmBinding\CollectionBinder.cs:448
NHibernate.Cfg.Configuration.SecondPassCompile() in c:\Users\sebros\Documents\My Projects\nhibernate-core\src\NHibernate\Cfg\Configuration.cs:1106
NHibernate.Cfg.Configuration.BuildSessionFactory() in c:\Users\sebros\Documents\My Projects\nhibernate-core\src\NHibernate\Cfg\Configuration.cs:1261
Orchard.Data.SessionFactoryHolder.BuildSessionFactory() in c:\svn\trunk\src\Apps\Orchard\src\Orchard\Data\SessionFactoryHolder.cs:91
Orchard.Data.SessionFactoryHolder.GetSessionFactory() in c:\svn\trunk\src\Apps\Orchard\src\Orchard\Data\SessionFactoryHolder.cs:69
Orchard.Data.SessionLocator.EnsureSession() in c:\svn\trunk\src\Apps\Orchard\src\Orchard\Data\SessionLocator.cs:109
Orchard.Data.SessionLocator.Demand() in c:\svn\trunk\src\Apps\Orchard\src\Orchard\Data\SessionLocator.cs:40
Orchard.Data.SessionLocator.For(Type entityType) in c:\svn\trunk\src\Apps\Orchard\src\Orchard\Data\SessionLocator.cs:34
Orchard.ContentManagement.DefaultContentManager.GetManyImplementation(QueryHints hints, Action`2 predicate) in c:\svn\trunk\src\Apps\Orchard\src\Orchard\ContentManagement\DefaultContentManager.cs:326
Orchard.ContentManagement.DefaultContentManager.Get(Int32 id, VersionOptions options, QueryHints hints) in c:\svn\trunk\src\Apps\Orchard\src\Orchard\ContentManagement\DefaultContentManager.cs:160
Orchard.ContentManagement.DefaultContentManager.Get(Int32 id, VersionOptions options) in c:\svn\trunk\src\Apps\Orchard\src\Orchard\ContentManagement\DefaultContentManager.cs:131
Orchard.ContentManagement.DefaultContentManager.Get(Int32 id) in c:\svn\trunk\src\Apps\Orchard\src\Orchard\ContentManagement\DefaultContentManager.cs:127
Orchard.Security.Providers.FormsAuthenticationService.GetAuthenticatedUser() in c:\svn\trunk\src\Apps\Orchard\src\Orchard\Security\Providers\FormsAuthenticationService.cs:110
Orchard.Security.CurrentUserWorkContext.<Get>b__0(WorkContext ctx) in c:\svn\trunk\src\Apps\Orchard\src\Orchard\Security\CurrentUserWorkContext.cs:13
Orchard.Environment.<>c__DisplayClass7`1.<FindResolverForState>b__5() in c:\svn\trunk\src\Apps\Orchard\src\Orchard\Environment\WorkContextImplementation.cs:37
Orchard.Environment.WorkContextImplementation.GetState(String name) in c:\svn\trunk\src\Apps\Orchard\src\Orchard\Environment\WorkContextImplementation.cs:28
Orchard.WorkContext.get_CurrentUser() in c:\svn\trunk\src\Apps\Orchard\src\Orchard\WorkContext.cs:60
Orchard.Security.Authorizer.Authorize(Permission permission, IContent content, LocalizedString message) in c:\svn\trunk\src\Apps\Orchard\src\Orchard\Security\Authorizer.cs:72
Orchard.Security.Authorizer.Authorize(Permission permission) in c:\svn\trunk\src\Apps\Orchard\src\Orchard\Security\Authorizer.cs:60
Orchard.Exceptions.DefaultExceptionPolicy.RaiseNotification(Exception exception) in c:\svn\trunk\src\Apps\Orchard\src\Orchard\Exceptions\DefaultExceptionPolicy.cs:69
Orchard.Exceptions.DefaultExceptionPolicy.HandleException(Object sender, Exception exception) in c:\svn\trunk\src\Apps\Orchard\src\Orchard\Exceptions\DefaultExceptionPolicy.cs:44
Orchard.Events.DefaultOrchardEventBus.TryNotifyHandler(IEventHandler eventHandler, String messageName, String interfaceName, String methodName, IDictionary`2 eventData, IEnumerable& returnValue) in c:\svn\trunk\src\Apps\Orchard\src\Orchard\Events\DefaultOrchardEventBus.cs:56
Orchard.Events.<NotifyHandlers>d__0.MoveNext() in c:\svn\trunk\src\Apps\Orchard\src\Orchard\Events\DefaultOrchardEventBus.cs:41
System.Linq.Buffer`1..ctor(IEnumerable`1 source) +520
System.Linq.Enumerable.ToArray(IEnumerable`1 source) +103
Orchard.Events.DefaultOrchardEventBus.Notify(String messageName, IDictionary`2 eventData) in c:\svn\trunk\src\Apps\Orchard\src\Orchard\Events\DefaultOrchardEventBus.cs:27
Orchard.Environment.State.DefaultProcessingEngine.Execute(Entry entry) in c:\svn\trunk\src\Apps\Orchard\src\Orchard\Environment\State\DefaultProcessingEngine.cs:101
Orchard.Environment.State.DefaultProcessingEngine.ExecuteNextTask() in c:\svn\trunk\src\Apps\Orchard\src\Orchard\Environment\State\DefaultProcessingEngine.cs:67
Orchard.Environment.DefaultOrchardHost.EndRequest() in c:\svn\trunk\src\Apps\Orchard\src\Orchard\Environment\DefaultOrchardHost.cs:230
Orchard.Environment.DefaultOrchardHost.Orchard.Environment.IOrchardHost.EndRequest() in c:\svn\trunk\src\Apps\Orchard\src\Orchard\Environment\DefaultOrchardHost.cs:82
Orchard.Web.MvcApplication.HostEndRequest(HttpApplication application, IOrchardHost host) in c:\svn\trunk\src\Apps\Orchard\src\Orchard.Web\Global.asax.cs:42
Orchard.WarmupStarter.Starter`1.OnEndRequest(HttpApplication application) in c:\svn\trunk\src\Apps\Orchard\src\Orchard.WarmupStarter\Starter.cs:75
Orchard.Web.MvcApplication.Application_EndRequest() in c:\svn\trunk\src\Apps\Orchard\src\Orchard.Web\Global.asax.cs:33

[TargetInvocationException: Exception has been thrown by the target of an invocation.]

System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor) +0
System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments) +229
System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) +193
System.Reflection.MethodBase.Invoke(Object obj, Object[] parameters) +35
System.Web.Util.ArglessEventHandlerProxy.Callback(Object sender, EventArgs e) +74
System.Web.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +80
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +165


Version Information: Microsoft .NET Framework Version:4.0.30319; ASP.NET Version:4.0.30319.18044

This error occured as soon as my module was enabled. Since it is an NHibernate exception I assumed it was caused either by a ContentPartRecord or by Migrations.cs. But I hadn’t changed anything in there. After searching for a root cause for a while (again, the exception didn’t help much in finding where the cause of the error could be found), I saw that I had created a class in the Models folder which had a property called Id. This class was neither ContentPartRecord nor referenced in Migrations.cs but I wondered whether the fact that Id is the default Identifier Property Name and it was indeed a string, maybe this was causing the problem. So I just renamed the property to something else and it solved my problem !

I am not too sure whether I only had this exception because the class was defined in the Models folder or whether it could have happened in any other folder. But I’m just not in the mood to try moving the class and renaming the property back to Id.

Setting the value of a variable in the Mono.CSharp Evaluator

When working with the Mono.CSharp Evaluator, you can define some variables and then use them later on to evaluate other expression. Here is a simple example:

using System;
using System.Reflection;
using Mono.CSharp;

namespace Playground
{
    class Program
    {
        static void Main(string[] args)
        {
            var evaluator = new Evaluator(new CompilerContext(new CompilerSettings { WarningLevel = 0, ShowFullPaths = true }, new ConsoleReportPrinter()));
            evaluator.Run("int i=0;");
            evaluator.Run("i=5+1;");
            string vars = evaluator.GetVars();
            Console.WriteLine(vars);
        }
    }
}

It defines a variable i and then sets it to some value. On the console, you will see:

int i=6

Now, sometimes you need to set the variable to a value which you cannot set so easily i.e. set it to a value which you cannot express with a string like 5+1.

There is unfortunately no method putVar(…) in the Evaluator class. Also the repository for variables which is internally maintained by the Evaluator is not exposed to you. But at least it does exist. So this means we’ll need some reflection to get to it.

First let’s have a look at the internal data maintained by the Evaluator:

Quick watch Evaluator

So the Evaluator has a non-public member called fields which is a collection of field definition/values. So what we need to do to set a value is either directly had an entry in there or modify an existing entry. Adding a new entry is kind of difficult because you need to define a Mono.CSharp.FieldSpec as item1 and this is no piece of cake. So our best shot is to use the Run method to create a variable. Once it is already in the fields member, we just need to update its item2 to the value we want to set.

First let’s get the fields member. We know it’s a non-public instance member so we can find it like this:

FieldInfo fieldInfo = typeof(Evaluator).GetField("fields", BindingFlags.NonPublic | BindingFlags.Instance);
var fields = fieldInfo.GetValue(evaluator) as Dictionary<string, Tuple<FieldSpec, FieldInfo>>;

Now we have the dictionary, we need to find the entry for our variable:

Tuple<FieldSpec, FieldInfo> tuple = fields["i"];

And then we can set item2 to the appropriate value:

tuple.Item2.SetValue(evaluator, 5 + 1);

That’s it. Putting it all together, you get the following code:

using System;
using System.Collections.Generic;
using System.Reflection;
using Mono.CSharp;

namespace Playground
{
    class Program
    {
        static void Main(string[] args)
        {
            var evaluator = new Evaluator(new CompilerContext(new CompilerSettings { WarningLevel = 0, ShowFullPaths = true }, new ConsoleReportPrinter()));
            evaluator.Run("int i=0;");
            FieldInfo fieldInfo = typeof(Evaluator).GetField("fields", BindingFlags.NonPublic | BindingFlags.Instance);
            if (fieldInfo != null)
            {
                var fields = fieldInfo.GetValue(evaluator) as Dictionary<string, Tuple<FieldSpec, FieldInfo>>;
                if (fields != null)
                {
                    Tuple<FieldSpec, FieldInfo> tuple = fields["i"];
                    if (tuple != null)
                    {
                        tuple.Item2.SetValue(evaluator, 5 + 1);
                    }
                }
            }
            string vars = evaluator.GetVars();
            Console.WriteLine(vars);
        }
    }
}

And as expected it writes int i=6 to the console. Of course in this case it makes no sense to do it this way as you could do it as shown at the beginning of the port with one line of code. But with this approach you can set values which are very complex and cannot be fully converted to a string.

If you do not like this approach, there is a question on StackOverflow which provides a few different ways to handle this issue.

Here is a short explanation as to why I did not use any of these 3 solution approaches:

  1. Use static or ThreadStatic variables: They have done a nice job in moving all methods of the Evaluator class from static methods to instance methods so that you can use different Evaluators in parallel and using static variables just takes us back to the time when only one Evaluator could be used.
  2. Return a delegate from your string code: The code I am interpreting is written by a used in a web UI. I am loading the value I want to set to a special variable using some class I do not want to give access to. The user should have access to the created object but not to the factory. Using this method means I need to add access to the assembly containing the factory, not only to the assembly containing the model.
  3. Go the full blown route: This basically has the same issue as the second solution.

So if you are not afraid to use reflection, need to be able to have multiple Evaluator instances in parallel and do not want to have the interpreter have access to the factory used to generate objects, the solution approach described in my post is the only one I can thing of.

Issue with Mono.CSharp and NRefactory

In a project I am working on, we’re using Mono.Scharp to interpret C# code at runtime (the code is entered by the user of the software). This can be done either with Mono.CSharp or using CSharpCodeProvider (part of Microsoft.CSharp). The nice thing about Mono.CSharp is that it’s implemented in a way that it’s easy to interpret code without needing to write a whole program around it. The error messages can thus directly be shown to the user since you do not need to add anything to their code before compiling or interpreting it.

If additionally to the dynamic code evaluation you also need to throw in some code completion, you can also use Mono.CSharp for it. But you’ll quickly notice that the Evaluator tends to hang forever with a high CPU usage on some expressions (especially when using the LINQ SQL syntax or when working with anonymous types). That’s the reason why I’ve decided to add NRefactory to the mix.

NRefactory works great. It provide a much better code completion than the Evaluator of Mono.CSharp does and it never chocks on code (or at least I haven’t observed it anymore after we switched). One problem is that NRefactory does rely on Mono.CSharp and that instead of having it as a dependency, it delivers it within its assembly. So this means that if you have both in your project, Visual Studio will keep complaining that it doesn’t Mono.CSharp.Evaluator is provided by both assemblies and it doesn’t know which one to use.

My first thought was to ditch Mono.CSharp as I get it from NRefactory anyway. But then I noticed that the Evaluator in NRefactory doesn’t seem to work at all with variables. Let’s have a look at a very simple program:

using System;
using System.Reflection;
using Mono.CSharp;

namespace Playground
{
    class Program
    {
        static void Main(string[] args)
        {
            var evaluator = new Evaluator(new CompilerContext(new CompilerSettings { WarningLevel = 0, ShowFullPaths = true }, new ConsoleReportPrinter()));
            evaluator.Run("int i=0;");
            string vars = evaluator.GetVars();
            Console.WriteLine(vars);
        }
    }
}

It just instanciates an evaluator and defines a variable i. Using Mono.CSharp.dll, you’ll see the following on the console:

int i = 0

If you now remove the reference to Mono.CShap.dll and add NRefactory in there (e.g. using the NuGet package manager), your code will still compile but you will get the following Exception at runtime:

(1,9): error CS0589: Internal compiler error during parsingSystem.NullReferenceException: Object reference not set to an instance of an object.
at Mono.CSharp.CSharpParser.case_794()
at Mono.CSharp.CSharpParser.yyparse(yyInput yyLex)
at Mono.CSharp.CSharpParser.parse()

Never found a way to get it working… So I looked for a solution using NRecfatory for code completion but Mono.CSharp for interpreting the code.

Basically, all you need to do is let the compiler know that when you write Mono.CSharp.xxx you mean the one in the Mono.CSharp.dll assembly and not the one in the NRefactory assembly. Once you’ve got both as references, you’ll get the following errors in your project:

Description File Line Column Project
Error 1 The type ‘Mono.CSharp.Evaluator’ exists in both ‘C:\Software\Visual Studio 2012\Projects\Playground\packages\ICSharpCode.NRefactory.5.3.0\lib\Net40\ICSharpCode.NRefactory.CSharp.dll’ and ‘C:\Software\Visual Studio 2012\Projects\Playground\packages\Mono.CSharp.3.0.6\Lib\net40\Mono.CSharp.dll’ C:\Software\Visual Studio 2012\Projects\Playground\Playground\Program.cs 11 33 Playground
Error 2 The type ‘Mono.CSharp.CompilerContext’ exists in both ‘C:\Software\Visual Studio 2012\Projects\Playground\packages\ICSharpCode.NRefactory.5.3.0\lib\Net40\ICSharpCode.NRefactory.CSharp.dll’ and ‘C:\Software\Visual Studio 2012\Projects\Playground\packages\Mono.CSharp.3.0.6\Lib\net40\Mono.CSharp.dll’ C:\Software\Visual Studio 2012\Projects\Playground\Playground\Program.cs 11 47 Playground
Error 3 The type ‘Mono.CSharp.CompilerSettings’ exists in both ‘C:\Software\Visual Studio 2012\Projects\Playground\packages\ICSharpCode.NRefactory.5.3.0\lib\Net40\ICSharpCode.NRefactory.CSharp.dll’ and ‘C:\Software\Visual Studio 2012\Projects\Playground\packages\Mono.CSharp.3.0.6\Lib\net40\Mono.CSharp.dll’ C:\Software\Visual Studio 2012\Projects\Playground\Playground\Program.cs 11 67 Playground
Error 4 The type ‘Mono.CSharp.ConsoleReportPrinter’ exists in both ‘C:\Software\Visual Studio 2012\Projects\Playground\packages\ICSharpCode.NRefactory.5.3.0\lib\Net40\ICSharpCode.NRefactory.CSharp.dll’ and ‘C:\Software\Visual Studio 2012\Projects\Playground\packages\Mono.CSharp.3.0.6\Lib\net40\Mono.CSharp.dll’ C:\Software\Visual Studio 2012\Projects\Playground\Playground\Program.cs 11 132 Playground

Now all you need to do is to select the reference to Mono.CSharp.dll in the Solution Explorer and modify the property Aliases to include not only global but an alias of your own e.g. MonoCSharp:

Mono.CSharp Alias

After that you can just reference this alias in your code:

extern alias MonoCSharp;

You can then use this as a prefix before using a type from Mono.CSharp:

var evaluator = new MonoCSharp::Mono.CSharp.Evaluator(
    new MonoCSharp::Mono.CSharp.CompilerContext(
        new MonoCSharp::Mono.CSharp.CompilerSettings { 
            WarningLevel = 0, 
            ShowFullPaths = true 
        }, new MonoCSharp::Mono.CSharp.ConsoleReportPrinter()
    )
);

Like this, you can reference both Mono.CSharp and NRefactory and still be able to use the better Evaluator from Mono.CSharp.dll.

Orchard CMS: SqlCeException: The data was truncated while converting from one data type to another.

While working on an Orchard CMS module, I got the following exception:

SqlCeException: The data was truncated while converting from one data type to another.

This happened in my Migrations class:

public class Migrations : DataMigrationImpl {
	public int Create() {
		// Creating table MyPartRecord
		SchemaBuilder.CreateTable("MyPartRecord",
			table =>
				table.ContentPartRecord()
					.Column("MyText", DbType.String));
		return 1;
	}
}

And the definition of my part was:

public class MyPart : ContentPart<MyPartRecord>
{
	[Required]
	public string MyText
	{
		get { return Record.MyText; }
		set { Record.MyText = value; }
	}
}

The problem is that when you use DbType.String without specifying a length, it creates a column of type NVARCHAR(255). And the string I was inserting was longer.

So an obvious solution is to set the length to something larger than 255 e.g.:

public class MyPart : ContentPart<MyPartRecord>
{
	[Required]
	[StringLength(2000)]
	public string MyText
	{
		get { return Record.MyText; }
		set { Record.MyText = value; }
	}
}

But since in my case the string the user enters can be very long and I do not really wanted to set any arbitrary limit, the best solution was to use the unlimited method on the column:

public class Migrations : DataMigrationImpl {
	public int Create() {
		// Creating table MyPartRecord
		SchemaBuilder.CreateTable("MyPartRecord",
			table =>
				table.ContentPartRecord()
					.Column<string>("MyText", x => x.Unlimited()));
		return 1;
	}
}

This way MyText is mapped to a column of type NTEXT and I can write as much text as I want into it (well not exactly but enough so that nobody will ever see the difference).

If you’ve already deployed your Orchard CMS module, you can just add an update method and change the column type:

public int UpdateFrom1()
{
	SchemaBuilder.AlterTable("MyPartRecord",
		table =>
		{
			table.AlterColumn("MyText", x => x.WithType(DbType.String).Unlimited());
		}
	);

	return 2;
}

For your reference, this is how DbType.String is registered in the MsSqlCeDialect in NHibernate:

RegisterColumnType(DbType.String, "NVARCHAR(255)");
RegisterColumnType(DbType.String, 4000, "NVARCHAR($l)");
RegisterColumnType(DbType.String, 1073741823, "NTEXT");

So if you do not specify a length, it will map it to an NVARCHAR(255). If you specify a length up to 4000 characters, it will map it to an NVARCHAR(X) where X is the defined length. If the length is over 4000, it will map it to an NTEXT.

Note that it is the same for the AnsiString:

RegisterColumnType(DbType.AnsiString, "NVARCHAR(255)");
RegisterColumnType(DbType.AnsiString, 4000, "NVARCHAR($l)");
RegisterColumnType(DbType.AnsiString, 1073741823, "NTEXT");

And fixed length strings only support more than 4000 characters:

RegisterColumnType(DbType.AnsiStringFixedLength, "NCHAR(255)");
RegisterColumnType(DbType.AnsiStringFixedLength, 4000, "NCHAR($l)");
...
RegisterColumnType(DbType.StringFixedLength, "NCHAR(255)");
RegisterColumnType(DbType.StringFixedLength, 4000, "NCHAR($l)");

Update: David Hayden has also written an interesting post regarding this topic.

How to create a properly escaped JavaScript string in Razor

I am working on a project in which I have a Razor view where I ouput JavaScript code calling a server method with ajax (using jQuery). It looks like this:

$(document).ready(function() {
	var inputVars =
	{
		"input": @Model.MyText
	};
	$.ajax({
		async: false,
		type: "POST",
		url: '@Url.Action("MyMethod", "MyController", new {area = "MyArea"})',
		dataType: "json",
		traditional: true,
		data: inputVars
	}).done(function(result) {
		if (result) {
			// Do something
		} else {
			// Log or show an error message
		}
		return false;
	});
}

The problem is that if MyText contains backslashes it doesn’t work. So I need to escape them. I just did it with a string replace. Then I saw that it also doesn’t work with newlines. So I escaped them as well. Then I noticed that it was also replacing < and > by &lt; and &gt;. So my list of string replaces was growing and growing. So I decided to create an helper class handling this. It has to solve two problems:

  1. Characters need to be properly escaped
  2. Since we’re not writing HTML but JavaScript code, we need to tell Razor not to additionally escape the string

For the first one, you just need to go through the input string and replace each character which needs escaping by a proper escape sequence.
For the second one, you need to return an IHtmlString to tell Razor that the string is already properly escaped and doesn’t require additional escaping.

The resulting helper looks like this:

using System.Text; // Required for StringBuilder
using System.Web;  // Required for IHtmlString

namespace Benohead.Helpers
{
	/// <summary>
	///  A class to help you output JavaScript code in a Razor view.
	/// </summary>
    public class BenoheadJavaScript
    {
        /// <summary>
        /// Encodes a c# string to a string which can be used in JavaScript code escaping the relevant characters
        /// </summary>
        /// <param name="input">the string to escape</param>
        /// <returns>a string which can be used in JavaScript code</returns>
        public static IHtmlString EncodeJavaScriptString(string input)
        {
            StringBuilder builder = new StringBuilder();
			// Open the double quotes
            builder.Append("\"");
			// Then add each character properly escaping them
            foreach (char c in input)
            {
                switch (c)
                {
					//First check whether it's one of the defined escape sequences
					case '\'': //single quote
						builder.Append("\\\'");
						break;
					case '\"': //double quote
						builder.Append("\\\"");
						break;
					case '\\': //backslash
						builder.Append("\\\\");
						break;
					case '\0': //Unicode character 0
						builder.Append("\\0");
						break;
					case '\a': //Alert (character 7)
						builder.Append("\\a");
						break;
					case '\b': //Backspace (character 8)
						builder.Append("\\b");
						break;
					case '\f': //Form feed (character 12)
						builder.Append("\\f");
						break;
					case '\n': //New line (character 10)
						builder.Append("\\n");
						break;
					case '\r': //Carriage return (character 13)
						builder.Append("\\r");
						break;
					case '\t': //Horizontal tab (character 9)
						builder.Append("\\t");
						break;
					case '\v': //Vertical quote (character 11)
						builder.Append("\\v");
						break;
					default:
						// If it's none of the defined escape sequences, convert the character to an int and check the code
						int i = (int)c;
						if (i >= 32 && i <= 127)
						{
							// if it's a displayable ASCII character, just write the character
							builder.Append(c);
						}
						else
						{
							// otherwise write the Unicode escape sequence for the character with hex value
							builder.AppendFormat("\\u{0:X04}", i);
						}
						break;
                }
            }
 			// Close the double quotes
           builder.Append("\"");
			// You have to return an IHtmlString otherwise an HTML escape will be performed e.g. < will be replaced by &lt;
            return new HtmlString(builder.ToString());
        }
    }
}

In order to use it, you need to add a using at the top of your cshtml file:

@using Benohead.Helpers

And wrap the reference to the model which are to be written as JavaScript strings with a call to EncodeJavaScriptString e.g.:

$(document).ready(function() {
	var inputVars =
	{
		"input": @BenoheadJavaScript.EncodeJavaScriptString(Model.MyText)
	};
	$.ajax({
		async: false,
		type: "POST",
		url: '@Url.Action("MyMethod", "MyController", new {area = "MyArea"})',
		dataType: "json",
		traditional: true,
		data: inputVars
	}).done(function(result) {
		if (result) {
			// Do something
		} else {
			// Log or show an error message
		}
		return false;
	});
}

Create anonymous types at runtime in C#

I am working on a project where I need to generate anonymous types at run-time based on some user input.

In order to do it, you will first need a pseudo-assembly where all the dynamic types will be stored:

AssemblyBuilder dynamicAssembly =
        AppDomain.CurrentDomain.DefineDynamicAssembly(new AssemblyName("MyDynamicAssembly"),
            AssemblyBuilderAccess.Run);

Then you need a module. You might be wondering what a module is. Every assembly has at least one module. In theory an assembly can contain multiple modules. And types belong to a module. So to summarize:

Assemblies contain modules and modules contain types

As Visual Studio doesn’t seem to support the creation of multi-module assemblies, you actually almost never need to care about modules. But you do need one to add types to an assembly. So let’s add a module to our assembly:

ModuleBuilder dynamicModule = dynamicAssembly.DefineDynamicModule("MyDynamicAssemblyModule");

Then we’ll create our dynamic type builder:

TypeBuilder dynamicType = dynamicModule.DefineType("MyDynamicType", TypeAttributes.Public);

Now that you have the type builder, you can create the type. But first I needed to add some properties backed by fields. This is a little bit trickier. At first I thought it’s enough to do something like this:

PropertyBuilder property = dynamicType.DefineProperty(propertyName, PropertyAttributes.None, propertyType, new[] {propertyType});

Unfortunately it just seems to create a property with no getter or setter, which is not very useful. Since I couldn’t find anyway to tell the DefineProperty method I needed more than an empty property, I decided to check the intermediate language code for some properties of a class and see what happened there.

In order to see the intermediate language code for a class, you have a few possibilities:

  • Use Sil. It is free and provides both a Visual Studio Addin and a standalone application.
  • ILSpy which is a free standalone application.
  • .Net Reflector which is a commercial standalone application as well as Visual Studio Addin.
  • other tools (there are plenty of tools out there but I’ve only ever used the three above.

So I created a simple auto-property called MyProperty and looked at the code generated by the C# compiler.

First the property definition itself:

  .property instance object MyProperty()
  {
    .get instance object MyNamespace.MyTestClass::get_MyProperty()
    .set instance void MyNamespace.MyTestClass::set_MyProperty(object)
  } // end of property MyTestClass::MyProperty

So no surprise here. It just links to getter and setter of the property to the get_MyProperty and set_MyProperty methods. Here the generated intermediate language code for these two methods:

  .method public hidebysig specialname instance object 
          get_MyProperty() cil managed
  {
    .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) 
    // Code size       11 (0xb)
    .maxstack  1
    .locals init (object V_0)
    IL_0000:  ldarg.0
    IL_0001:  ldfld      object MyNamespace.MyTestClass::'<MyProperty>k__BackingField'
    IL_0006:  stloc.0
    IL_0007:  br.s       IL_0009

    IL_0009:  ldloc.0
    IL_000a:  ret
  } // end of method MyTestClass::get_MyProperty

  .method public hidebysig specialname instance void 
          set_MyProperty(object 'value') cil managed
  {
    .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) 
    // Code size       8 (0x8)
    .maxstack  8
    IL_0000:  ldarg.0
    IL_0001:  ldarg.1
    IL_0002:  stfld      object MyNamespace.MyTestClass::'<MyProperty>k__BackingField'
    IL_0007:  ret
  } // end of method MyTestClass::set_MyProperty

The code for set_MyProperty is pretty straightforward:

  1. Load the object on the evaluation stack
  2. Load the value on the evaluation stack
  3. Replace the value of the backing field of the object with the value on the stack

But the get_MyProperty code seemed to complex. It’s basically doing the following:

  1. Load the object on the evaluation stack
  2. Get the value of the backing field of this object on the stack
  3. Store the value from the stack in the local variable list
  4. Jump to the next instruction
  5. Load the value from the local variable list to the stack

Basically the last 3 steps are not required. So you can optimize it to just loading the object and fetching the value of the backing field to the stack.

OK, now we know what we need to do:

  1. Define a backing field
  2. Define a property
  3. Define a get method
  4. Execute the IL code above
  5. Define a set method
  6. Execute the IL code above

That sounds very complex just to define a property dynamically but I haven’t found any easier way. The code then looks like this:

public static void AddProperty(TypeBuilder typeBuilder, string propertyName, Type propertyType)
{
    const MethodAttributes getSetAttr = MethodAttributes.Public | MethodAttributes.HideBySig;

    FieldBuilder field = typeBuilder.DefineField("_" + propertyName, typeof (string), FieldAttributes.Private);
    PropertyBuilder property = typeBuilder.DefineProperty(propertyName, PropertyAttributes.None, propertyType,
        new[] {propertyType});

    MethodBuilder getMethodBuilder = typeBuilder.DefineMethod("get_value", getSetAttr, propertyType,
        Type.EmptyTypes);
    ILGenerator getIl = getMethodBuilder.GetILGenerator();
    getIl.Emit(OpCodes.Ldarg_0);
    getIl.Emit(OpCodes.Ldfld, field);
    getIl.Emit(OpCodes.Ret);

    MethodBuilder setMethodBuilder = typeBuilder.DefineMethod("set_value", getSetAttr, null,
        new[] {propertyType});
    ILGenerator setIl = setMethodBuilder.GetILGenerator();
    setIl.Emit(OpCodes.Ldarg_0);
    setIl.Emit(OpCodes.Ldarg_1);
    setIl.Emit(OpCodes.Stfld, field);
    setIl.Emit(OpCodes.Ret);

    property.SetGetMethod(getMethodBuilder);
    property.SetSetMethod(setMethodBuilder);
}

Once you’ve called this method to add the property (or multiple properties), all you have to do is call the CreateType method on the TypeBuilder to get an actual dynamic type:

Type myType = dynamicType.CreateType();

That’s it ! It took me forever to figure out but I learned a lot along the way !

The name DbType does not exist in the current context

I have installed the Orchard CMS in WebMatrix and was creating a new module. When I came to the migration file, I got the following error:

The name DbType does not exist in the current context

The following includes had been automatically added to the migration file by the Orchard Code Generator:

using System;
using System.Collections.Generic;
using System.Data;
using Orchard.ContentManagement.Drivers;
using Orchard.ContentManagement.MetaData;
using Orchard.ContentManagement.MetaData.Builders;
using Orchard.Core.Contents.Extensions;
using Orchard.Data.Migration;

This actually looked good since DbType is defined in System.Data. The problem was just that the using was there but the reference to the System.Data framework assembly was missing. So I just right-clicked on my Orchard CMS website in Visual Studio and selected “Add reference…”. You then see a dialog where you can choose Assemblies > Framework on the left hand side and then select the checkbox next to System.Data in the middle pane. Then press OK and the errors are gone !

System.TypeLoadException: Method does not have an implementation.

I’m working on a C# project where I have a WCF service using an external library and providing some functionality through a REST interface. For some reason, it broke at some point in time and I was getting the following error message:

System.TypeLoadException: Method ‘XXX’ in type ‘YYY’ from assembly ‘ZZZ’ does not have an implementation.

First, since I had the code for the external library (I actually built it from source), I checked the code. The method XXX was actually available with an implementation in type YYY.

Here is how the different assemblies look like:

Assemblies

After a few hours I did figure out that the problem was that I had referenced an old version of the interfaces assembly when building the implementation assembly and a new version of the interfaces assembly when building the services assembly. So the implementation was actually there. It was just not marked as being the implementation of the method defined in the interface but was just marked as an additional method present in the implementation. So accessing the method through the interface in the service failed.

After recompiling the implementation assembly with a reference to the newest interfaces assembly solved the problem.

Since I have over 15 years of experience on the Java platform and about 4 years of experience on the .NET platform, I tend to always relate everything I see on the .NET platform to the way it works in Java. So after finding the solution to this issue, I decided to check how the behavior in Java would be in this case.

I’ve first created an interface:

public interface IMyInterface {
	public void myFirstMethod();
}

Then I’ve created an implementation:

public class MyImplementation implements IMyInterface {
	public void myFirstMethod() {
		System.out.println("myFirstMethod");
	}

	public void mySecondMethod() {
		System.out.println("mySecondMethod");
	}
}

Finally, I’ve implemented a service instantiating the implementation and calling the first method through the interface:

public class MyService {
	public static void main(String[] args) {
		IMyInterface myInt = new MyImplementation();
		myInt.myFirstMethod();
	}
}

Running the service displays:

myFirstMethod

Then I’ve updated the interface adding the second method:

public interface IMyInterface {
	public void myFirstMethod();
	public void mySecondMethod();
}

I’ve then added a call to the second method in the service without recompiling the implementation with the new interface:

public class MyService {
	public static void main(String[] args) {
		IMyInterface myInt = new MyImplementation();
		myInt.myFirstMethod();
		myInt.mySecondMethod();
	}
}

Compiling the service again and running it displays:

myFirstMethod
mySecondMethod

So I didn’t get the same issue here.

Note that this post is not about which platform is better and whether the Java behavior makes more sense than the .NET behavior or not.
With the way Java behaves I wouldn’t have run into this problem. On the other hand, I wouldn’t have noticed that I built the implementation classes against the wrong version of the interface. If the implementation actually didn’t implement mySecondMethod, I wouldn’t have noticed it either and would have got an exception like:

Exception in thread "main" java.lang.AbstractMethodError: MyImplementation.mySecondMethod()V
at MyService.main(MyService.java:5)

Also if I had handled versioning properly on the .NET side, I would probably not wasted that much time. I guess it’s always the thing with versioning: it’s easier to assume that there is only one version of a given interface and that all components use the same one, than handling multiple versions and having different assemblies built against different versions of another assembly. On the other hand, assuming this often just means that if you do not have a build system making sure that all components are recompiled against the latest version of an interface, you’ll get some nice exceptions at runtime.

Sybase: Access the database with C# using ODBC

I needed to write a very short C# program to access a Sybase ASE database and extract some information.

First had to download the appropriate version of ASE. It contains a directory called \archives\odbc. There is a setup.exe. Just run it.

Now there a new driver available:

create new data sourceThere is no need to add a data source to access ASE from an ODBC connection using C#. Just went there to check whether the driver was properly installed.

Then just create a program connecting to ASE using the following connection string:

Driver={Adaptive Server Enterprise};server=THE_HOSTNAME;port=2055;db=THE_DB_NAME;uid=sa;pwd=THE_SA_PASSWORD;

If you omit the db=… part, you’ll just land in the master database.

With this connection, you can then execute statements.

Here a sample code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Odbc;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            String errorMsg;
            OdbcConnection con = Connect("sa", "sa.pwd", "2055", "192.168.190.200", "mydb", out errorMsg);
            Console.WriteLine(errorMsg);
            if (con != null)
            {
                Console.WriteLine("In database {0}", con.Database);
                OdbcCommand command = con.CreateCommand();
                command.CommandText = "SELECT name FROM sysobjects WHERE type='U' ORDER BY name";
                OdbcDataReader reader = command.ExecuteReader();
                int fCount = reader.FieldCount;
                for (int i = 0; i < fCount; i++)
                {
                    String fName = reader.GetName(i);
                    Console.Write(fName + ":");
                }
                Console.WriteLine();
                while (reader.Read())
                {
                    for (int i = 0; i < fCount; i++)
                    {
                        String col = reader.GetValue(i).ToString();
                        Console.Write(col + ":");
                    }
                    Console.WriteLine();
                }
                reader.Close();
                command.Dispose();
                Close(con);
                Console.WriteLine("Press any key too continue...");
                Console.ReadLine();
            }
        }

        private static OdbcConnection Connect(String strUserName, String strPassword, String strPort, String strHostName, String dbName, out String strErrorMsg)
        {
            OdbcConnection con = null;
            strErrorMsg = String.Empty;
            try
            {
                String conString = "Driver={Adaptive Server Enterprise};server=" + strHostName + ";" + "port=" + strPort + ";db=" + dbName + ";uid=" + strUserName + ";pwd=" + strPassword + ";";
                con = new OdbcConnection(conString);
                con.Open();
            }
            catch (Exception exp)
            {
                con = null;
                strErrorMsg = exp.ToString();
            }

            return con;
        }

        private static void Close(OdbcConnection con)
        {
            con.Close();
        }
    }
}

That was really easy ! Not that it’d have been more difficult with Java or PHP, but I’d have expected to waste ours making mistakes and trying to debug it…