Orchard: new installation leads to an HTTP 500 – Internal Server Error

Since I got a new computer (or rather an old one repaired), I first installed IIS switched the DefaultAppPool to .NET Framework Version 4.0 and deployed Orchard from my solution.

When I then open Orchard in my browser, all I got is a white page. Looking at the IIS log files shows that an internal server error:

2014-02-07 10:26:48 127.0.0.1 GET /orchard – 80 – 127.0.0.1 Mozilla/5.0+(Windows+NT+6.1;+WOW64;+rv:27.0)+Gecko/20100101+Firefox/27.0 500 19 33 1

This unfortunately didn’t help much. Then I remember that I already once had a similar and had to use the ASP.NET IIS Registration Tool to install the version of ASP.NET and register ASP.NET in IIS by executing the following in a DOS prompt:

cd C:\Windows\Microsoft.NET\Framework64\v4.0.30319
aspnet_regiis.exe -i

After doing this and setting the rights for the DefaultAppPool user again so that Orchard can write to the App_Data directory, my Orchard Installation was working fine.

It’s just a pity that there is not a clear error message written to the log file in such cases…

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.

ASP.NET MVC: The required anti-forgery form field “__RequestVerificationToken” is not present

When working on an ASP.NET MVC project, you might get the following error message:

The required anti-forgery form field “__RequestVerificationToken” is not present

As the message says, this means that you’re missing the anti-forgery verification token. This token is used to prevent cross-site request forgery (CSRF) attacks. A CSRF attack is similar to a cross-site scripting (XSS) exploit but the other way around. In an XSS exploit, someone is using the fact that a user trusts a site and in a CSRF attack someone is using the fact is trusting a given user e.g. commands are sent to the server pretending to come from the user.

A very simple example of such an attack is to have a trusted user load a web page from a third party server and include a call to the target server e.g. in an image tag e.g.:

<img src="http://targetserver/importantfunction">

If the target server relies only on cookies for security, the user might have a still valid cookie and the server will not notice that it is actually an attack.

Of course this won’t work if you only accept POST requests but you could implement something like this using ajax.

To prevent this, the server has to implement an own protection mechanism instead of relying on the browser. One way to do it is to include in all forms a special random token linked to a cookie or the user session. When a call is received, if the form data do not contain this token (usually some random GUID), the request is rejected.

On the other hand, the token is present on the page so it’s not really secret. But because of the same-origin policy the attacker cannot read the token from the page (Cross-origin writes are allowed but cross-origin reads are typically not allowed).

In ASP.NET MVC you can define a method as requiring such a token by defining the ValidateAntiForgeryToken attribute e.g.:

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult MyAction(string id) {
}

Note that when working with Orchard CMS even though your controller doesn’t define this attribute, the anti-forgery validation will happen.

When you use a form, you can handle the anti-forgery token by using the AntiForgeryToken() method of the Html helper e.g.:

@using (Html.BeginForm()) {
    @Html.AntiForgeryToken()
    <input ...>
}

This will add an invisible field with the name __RequestVerificationToken in the form. This token will then be submitted with the form and checked on the server before processing the form.

Now I use a lot of ajax calls to the server using jquery e.g.:

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

This call will fail with the error message in the title of this post. What you need to do is get the token from a form on the page and send it along the other call parameters. To fetch the value of the token, you can use jQuery as well:

$('input[name=__RequestVerificationToken]').val()

This will find the input field for the token (in a form on the page) and fetch the value. You then need to append it to the data sent to the server:

$.ajax({
	type: "POST",
	url: '@Url.Action("MyMethod", "MyController", new {area = "MyArea"})',
	dataType: "json",
	traditional: true,
	data: { "id": "12345678", "__RequestVerificationToken": $('input[name=__RequestVerificationToken]').val() };
}).done(function(result) {
	if (result) {
		// Do something
	} else {
		// Log or show an error message
	}
	return false;
});

The error is gone and the call is processed successfully. Now if you have many ajax calls on a page, it’s kind of a pain to add this to all calls. So you should rather create a helper function which will add the token to the data sent to the server:

function addRequestVerificationToken(data) {
	data.__RequestVerificationToken = $('input[name=__RequestVerificationToken]').val();
	return data;
};

You can then use it like this:

function addRequestVerificationToken(data) {
	data.__RequestVerificationToken = $('input[name=__RequestVerificationToken]').val();
	return data;
};
$.ajax({
	type: "POST",
	url: '@Url.Action("MyMethod", "MyController", new {area = "MyArea"})',
	dataType: "json",
	traditional: true,
	data: addRequestVerificationToken( { "id": "12345678" } );
}).done(function(result) {
	if (result) {
		// Do something
	} else {
		// Log or show an error message
	}
	return false;
});

If you use Orchard CMS you will see that the parts in an editor template are displayed within one form so you do not need to add a form. But when viewing content items, you usually do not require a form. So in this case you’ll have to add a form without submit, just to get the token:

@using (Html.BeginForm()) {
    @Html.AntiForgeryToken()
}

Also if you use Orchard CMS instead of manually fetching the value of the verification token, you could also use the helper provided by Orchard:

function addAntiForgeryToken(data) {
    data.__RequestVerificationToken = "@Html.AntiForgeryTokenValueOrchard()";
    return data;
};