Noah Blumenthal's Blog

July 10, 2009

Model Binder that retrieves from DB

Filed under: Uncategorized — noahblu @ 2:20 am

Many times I need a model binder that will retrieve my model from a repository so that I can perform updates.  Here’s what I came up with.

   1: public class EntityRetrievalBinder<T, TRepository> : IModelBinder

   2:     where TRepository : IRepository<T>

   3: {

   4:     #region IModelBinder Members

   5:  

   6:     public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)

   7:     {

   8:         var name = bindingContext.ModelName + ".ID";

   9:         ValueProviderResult idResult;

  10:         try

  11:         {

  12:             if (bindingContext.ValueProvider.TryGetValue(name, out idResult))

  13:             {

  14:                 Guid id = new Guid(idResult.AttemptedValue);

  15:                 var repository = StructureMap.ObjectFactory.GetInstance<TRepository>();

  16:                 T obj = repository.FindById(id);

  17:                 if (obj == null)

  18:                     throw new ArgumentException("Object not found");

  19:                 return obj;

  20:             }

  21:         }

  22:         catch (Exception e)

  23:         {

  24:         }

  25:         return null;

  26:     }

I changed a couple things for this post, but basically the logic is simple.  What this does is just retrieve the repository from StructureMap and then try to run the Find() method which takes a Guid ID as its only parameter.  Either this will return a null (if no ID was posted) or an object of type T OR it might throw an exception if the user posted an ID but that ID was not found.  I’ll show you in the next post how I tie everything together.

Changed site template

Filed under: Uncategorized — noahblu @ 2:15 am

I’m toying with a Code Snippet plugin for Live Writer that allows me to insert code snippets that are actually legible (check the previous post to see).  However, this wasn’t working well with my last template so I changed templates.

ASP.NET Custom Model Binder Template

Filed under: Uncategorized — noahblu @ 2:09 am

I have found that I build a lot of the same logic into my Model Binders.  I typically use Reflection to either instantiate a new object or call a method on a Factory that will do that for me.  So I’ve put together a ModelBinder using the Template pattern to help accomplish this more easily.

First, the Template:

   1: public abstract class ReflectionModelBinder : DefaultModelBinder

   2:     {

   3:         private IModelBinderValidator _validator = null;

   4:         public ReflectionModelBinder() { }

   5:         public ReflectionModelBinder(IModelBinderValidator validator)

   6:         {

   7:             _validator = validator;

   8:         }

   9:         protected override object CreateModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Type modelType)

  10:         {

  11:             ParameterInfo[] parameters = GetParameters();

  12:             List<object> paramValues = new List<object>();

  13:             IModelBinder binder;

  14:             string oldModelName = bindingContext.ModelName;

  15:             foreach (ParameterInfo param in parameters)

  16:             {

  17:                 string name = CreateSubPropertyName(oldModelName, param.Name);

  18:                 bindingContext.ModelType = param.ParameterType;

  19:                 bindingContext.ModelName = name;

  20:                 if (!System.Web.Mvc.ModelBinders.Binders.TryGetValue(param.ParameterType, out binder))

  21:                     binder = System.Web.Mvc.ModelBinders.Binders.DefaultBinder;

  22:                 object model = binder.BindModel(controllerContext, bindingContext);

  23:                 paramValues.Add(model);

  24:             }

  25:             bindingContext.ModelType = modelType;

  26:             bindingContext.ModelName = oldModelName;

  27:             object obj = CreateModel(paramValues.ToArray());

  28:  

  29:             if (_validator != null)

  30:                 _validator.Validate(bindingContext, obj);

  31:  

  32:             return obj;

  33:         }

  34:         protected abstract ParameterInfo[] GetParameters();

  35:         protected abstract object CreateModel(object[] parameters);

  36:     }

(don’t mind the IModelBinderValidator, that’ll have to be another post, but you can probably figure it out)

So now I have this template.  Here’s an example of how I can bind a model by using a Factory (I have a Lease object with a LeaseFactory  that creates the lease and all the associated charges like back rent etc.):

   1: public class LeaseReflectionModelBinder : ReflectionModelBinder

   2: {

   3:     public LeaseReflectionModelBinder(IModelBinderValidator validator) : base(validator)

   4:     {

   5:         _createLeaseMethod = typeof(LeaseFactory).GetMethod("CreateLease", BindingFlags.Static | BindingFlags.Public);

   6:     }

   7:     private MethodInfo _createLeaseMethod;

   8:  

   9:     protected override ParameterInfo[] GetParameters()

  10:     {

  11:         return _createLeaseMethod.GetParameters();

  12:     }

  13:  

  14:     protected override object CreateModel(object[] parameters)

  15:     {

  16:         return _createLeaseMethod.Invoke(null, parameters);

  17:     }

  18: }

Easy, huh?

July 7, 2009

Connections to SQL Server files (*.mdf) require SQL Server Express 2005 to function properly

Filed under: Uncategorized — noahblu @ 4:34 pm

Setup a new machine with VS2008 & SQL Server Express 2008 and was surprised when I got the following error when trying to run against an mdf file:

Connections to SQL Server files (*.mdf) require SQL Server Express 2005 to function properly

Well I have SQL Server Express 2008 installed!  And my other machines don’t have this problem.  Next step was to try installing SP1 — doh, that’ll fix it, right?  WRONG!  Same error.

After 30 min of googling, I stumbled upon this MS article http://support.microsoft.com/kb/957944 .  Cause?

This problem occurs because Visual Studio 2008 SP1 incorrectly detects some registry keys for a 64-bit installation of SQL Server Express 2008.

So the issue is that I’m running a 64bit SQL Server instance.

There’s a hotfix too.  But there’s no link (it took me 5 min of searching the page to finally figure this out and RTFM) — you have to call MS and have them send it to you.  That’s not terrible and it only took my a few min, but it was kind of a pain.

In case you have this issue, you can save yourself some time by dialing the direct number to the department that can help you: 1-800-936-4900.

June 17, 2009

jEditable note: don’t return JSON (and how to return strings from ASP.NET MVC Actions)

Filed under: ASP.NET MVC,jQuery — noahblu @ 5:42 pm

jEditable is a cool jQuery plugin for inline editing.  I was toying around with it today and found an interesting ‘feature’: it expects a string response from the server.  Now that’s a problem because I was returning a JSON object so my string had quotes around it (Test became “Test”).  Ok, so I have to return a regular string.  I guess I just didn’t expect that because I’m used to my jQuery plugins expecting json (or at least accepting it).

Well, my Action returns an ActionResult because not always will it be accessed via jQuery (yup, this does not actually require javascript!).  I check the request (if (Request.IsAjaxRequest())) and proceed…
So, what I did was create a StringResult.  Much like the JsonResult class, the StringResult outputs the data you give it but it just outputs text.  Simple but effective, here’s the code:

public class StringResult : ActionResult
 {
 private string _output;
 public StringResult(string output)
 {
 _output = output;
 }
 public override void ExecuteResult(ControllerContext context)
 {
 HttpResponseBase response = context.HttpContext.Response;
 response.ContentType = "text/html";
 response.Write(_output);
 }
 }

June 15, 2009

ModelBinder for objects without default constructors

Filed under: Uncategorized — noahblu @ 4:46 pm

My DDD Value Objects don’t have default constructors.  Neither do many of my entity objects — I like having my objects valid on instantiation.  But ASP.NET’s DefaultModelBinder doesn’t know how to instantiate these objects.  I created a ConstructorModelBinder to achieve this functionality.  The code is below.  Keep in mind that this will currently use the constructor with the most parameters.

You use it by specifying something like this in the Global.asax:

System.Web.Mvc.ModelBinders.Binders.Add(typeof(MyClass), new ConstructorModelBinder<MyClass>());

public class ConstructorModelBinder<T> : DefaultModelBinder
 {
 protected override object CreateModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Type modelType)
 {
 Type type1 = typeof(T);
 ConstructorInfo[] constructors = type1.GetConstructors();
 ConstructorInfo largestConstructor = constructors.OrderByDescending(x => x.GetParameters().Count()).First();
 ParameterInfo[] parameters = largestConstructor.GetParameters();
 List<object> paramValues = new List<object>();
 IModelBinder binder;
 string oldModelName = bindingContext.ModelName;
 foreach (ParameterInfo param in parameters)
 {
 string name = CreateSubPropertyName(oldModelName, param.Name);
 bindingContext.ModelType = param.ParameterType;
 bindingContext.ModelName = name;
 if (!System.Web.Mvc.ModelBinders.Binders.TryGetValue(param.ParameterType, out binder))
 binder = System.Web.Mvc.ModelBinders.Binders.DefaultBinder;
 object model = binder.BindModel(controllerContext, bindingContext);
 paramValues.Add(model);
 }
 bindingContext.ModelType = typeof(T);
 bindingContext.ModelName = oldModelName;
 object obj = Activator.CreateInstance(type1, paramValues.ToArray());
 return obj;
 }
 }

May 25, 2009

Script# interesting namespace “feature”

Filed under: Uncategorized — noahblu @ 5:10 pm

Take a look at this code:

System.DHTML.Window.Event.ReturnValue = false;

Now take a look at this code:

using System.DHTML
…..
Window.Event.ReturnValue = false;

Do they look the same to you?

Because they don’t look the same to Script#!

The former doesn’t compile “Check that your C# source compiles and that you are not using an unsupported feature.” and the latter does.  Interested little quirk, huh?

May 22, 2009

Debug is not defined (FireFox 3.0.10)

Filed under: Uncategorized — noahblu @ 6:15 pm

I spent a long time today trying to track down an issue whereby all my Javascript code worked in IE but none worked on Firefox (that’s a first!!!).

I found I kept getting the following error in the FF Javascript console:

Debug is not defined

of course always followed by lots of other errors. I found I had to add an empty Debug function in javascript above the rest of my code:

function Debug(){}

Quite a hack, huh?

I’m using Script# (http://projects.nikhilk.net/ScriptSharp/) to build much of my JS framework (I highly recommend) and it relies on this Debug object.

WTF?!?!

May 8, 2009

Checking equalities of object properties in NUnit

Filed under: Uncategorized — noahblu @ 4:59 pm

I’m retrieving some information from a DB and I wanted to check not only that two objects are equal (which might mean that their persistance ID is the same) but that their properties are equal too.  I wrote the following code to do this.  It’s pretty simple and probably isn’t going to do everything I need down the line, but for the test case at hand it worked well.  Feel free to use it but if you improve it I’d love to hear about it.

public static void PropertiesAreEqual(object o1, object o2)
 {
     Type o1Type = o1.GetType();
     Assert.IsInstanceOfType(o1.GetType(), o2);
     System.Reflection.PropertyInfo[] o1Properties = o1Type.GetProperties();
     Type o2Type = o2.GetType();
     foreach (System.Reflection.PropertyInfo prop in o1Properties)
    {
         Console.WriteLine("Checking... " + prop.Name);
         object o1Value = prop.GetValue(o1, null);
         object o2Value = o2Type.GetProperty(prop.Name).GetValue(o2, null);
         Assert.AreEqual(o1Value, o2Value);
     }
 }

SqlCE Unable to load DLL “sqlceme35.dll” exception on Vista x64

Filed under: Uncategorized — noahblu @ 4:24 pm

I ran into a wall today when I tried testing my NHibernate repositories against a SQLCE Database.

After:
1) Referencing System.Data.SqlCE and
2) Setting Copy Local on that DLL to True (this is required for NHibernate because it expects the DLL in the local directory)

I still was getting an excpetion:

Unable to load DLL “sqlceme35.dll

I found this post about it:

http://pietschsoft.com/post/2009/01/SQL-Compact-And-The-Unable-to-load-DLL-sqlceme35dll-Runtime-Exception.aspx

And realized it must be my 64-bid Vista. I downloaded the SP1 from here:

http://www.microsoft.com/downloads/details.aspx?FamilyId=DC614AEE-7E1C-4881-9C32-3A6CE53384D9&displaylang=en#filelist

And everything worked fine.

« Previous PageNext Page »

Blog at WordPress.com.