Sunday, June 13, 2010

Practical MongoDB Part 3: Fine Tuning

In Part 1 of this series I briefly discussed setting up MongoDB to run as a service. In Part 2 I covered data access objects. In this installment I'd like to touch on embedded documents before reviewing a few configuration changes you should use to improve performance.

Thursday, June 10, 2010

Practical MongoDB Part 2: NoRMalized Data Access

In Part 1 of this series I demonstrated setting up MongoDB to run as a Windows service. In this segment, I'll show you how I setup my data access layers using NoRM.

Practical MongoDB Part 1: Up and Running

Like many others, I've been intrigued by the NoSQL movement and the various alternatives which have appeared in recent years. One of these options which is rapidly growing in popularity is MongoDB, a document oriented database written in C++ with scalability in mind.

This post is the first in a series documenting my attempts to implement MongoDB into a real world project.

MongoDB has garnered a following in the ruby and php communities, but up until recently had little exposure to .Net folks. The earliest .Net driver, mongodb-csharp, was basically a wrapper on Mongo's built in capabilities. While useful, this design did little to provide a strongly typed approach to data access. More recently however, another open source effort led by Andrew Theken and Rob Conery created NoRM: a strongly typed driver (which even has a sweet Linq provider). There are other C# drivers out there, but these are the ones I have experienced. Part 2 and onward of this series will use NoRM.


Thursday, April 15, 2010

MVC 2: JsonRequestBehavior DenyGet

We migrated one of our projects to MVC 2 today, and one of the first things I noticed is that all my ajaxified jsony sweetness had stopped working! A quick look at the XHR revealed the following server error.
This request has been blocked because sensitive information could be disclosed to third party web sites when this is used in a GET request. To allow GET requests, set JsonRequestBehavior to AllowGet.
What the heck?

A quick Google turned up a couple articles about MVC 2's new JsonRequestBehavior, and specifically the MSDN article (the link to Haack is dead, so here's a good one). Ok, good to know. I wasn't aware of that vulnerability, but in the mean time I need this project working.

I could modify the actions to call a Json overload which accepts the JsonRequestBehavior.
  return Json(myjson, JsonRequestBehavior.AllowGet);
But since I have somewhere between 50-80 Json actions in this app, that would be a lot of find-replace. Plus, when I finish modifying my client library to use POST requests, I would have to do it all over again. A one stop solution would be much preferable.

If your project already uses a base controller class, you can do one simple override:
protected override JsonResult Json(object data, string contentType,
Encoding contentEncoding, JsonRequestBehavior behavior)
{
// TODO: change all my GET Json request into POST
return base.Json(data, contentType, contentEncoding,
JsonRequestBehavior.AllowGet);
}
Keep in mind this should be a temporary crutch only!

IIS 7 (7.5): Hosting Multiple SSL Sites On One IP

Since I continually find myself Googling this information whenever I add a new site on our wildcard cert, I figured I'd document it here.

Adding a New Binding:

Requirements:
  1. A wild card SSL certificate (of the form *.domain.com). I assume the cert is already installed on your server.
  2. An IP you wish to use on multiple IIS sites.
  3. Two or more IIS sites with no SSL binding (I'll touch on changing a binding at the end).
With these in place, adding an SSL cert is quite simple:
  1. In an elevated command prompt navigate to
    C:\Windows\System32\inetsrv
  2. Enter the following command (replace {SITENAME}, {IP}, and {HOSTHEADER} with the appropriate values).
    appcmd set site /site.name:{SITENAME} /+bindings.[protocol='https',bindingInformation='{IP}:443:{HOSTHEADER}']
  3. Check the selected cert in IIS via the bindings window. You can change the cert here, but you cannot change the host header.
That's it.

Changing an Existing Binding:

Changing a binding is similar to the adding binding with a few alterations to the command
appcmd set site /site.name:{SITENAME} /bindings.[protocol='https',bindingInformation='{IP}:443:{HOSTHEADER}'].bindingInformation:{NEWIP}:443:{NEWHOSTHEADER}

Wednesday, January 20, 2010

NHibernate: Is That Type a Proxy?

One of our applications does some reflection to map customizable content to domain objects. Anyone familiar with NHibernate and lazy loading has probably encountered proxy classes before. My problem: given a Type, I want the domain type.

It's easy to find out that proxy types extend the domain type they represent, so if I know that my Type is a proxy I can call BaseType to get the domain type. But how do I know if my Type is a proxy?

I tried numerous approaches, but the simplest I found was to look for a specific interface. Turns out proxies implement an interface called INHibernateProxy.

if (clazz.GetInterface(typeof(INHibernateProxy).FullName) != null)
clazz = clazz.BaseType;

Now clazz represents the domain type as desired.

There are other solutions of course, such as detecting the namespace (proxies have none), and possibly checking IsAutoClass (which I couldn't confirm in any documentation). This approach seems the most reliable.

Friday, January 8, 2010

NHibernate: Mapping a Generic List of Enum

I recently ran into a case where I wanted to have a collection of an enumeration on one of my domain classes.

E.g.

public class MyDomainClass
{
public List<MyRoleEnum> Roles { get; set; }
}

But how is do we map something like this in an xml mapping? A quick google didn't turn up the answer, so I played around a bit and found the following works as desired.

<bag name="Roles" table="MyDomainClass2Role">    
<key column="MyDomainClassId" />
<element column="Role" type="MyRoleEnum" />
</bag>

To confirm this usage I checked the documentation at hibernate.org. Turns out the <element /> tag was designed for value type bags anyway.