views:

232

answers:

2

I have a model like this;

public class QuickQuote
{
    [Required]
    public Enumerations.AUSTRALIA_STATES  state { get; set; }

    [Required]
    public Enumerations.FAMILY_TYPE familyType { get; set; }

As you can see the two proerties are enumerations.

Now I want to employ my own model binder for reasons that I won't bother getting into at the moment.

So I have;

public class QuickQuoteBinder : DefaultModelBinder
{

    public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        quickQuote = new QuickQuote();

        try
        {
            quickQuote.state = (Enumerations.AUSTRALIA_STATES)
                Enum.Parse(typeof(Enumerations.AUSTRALIA_STATES),
                bindingContext.ValueProvider.GetValue(bindingContext.ModelName + ".state").AttemptedValue);
        }
        catch {
            ModelState modelState = new ModelState();
            ModelError err = new ModelError("Required");
            modelState.Errors.Add(err);
            bindingContext.ModelState.Add(bindingContext.ModelName + ".state", modelState);
        }

The problem is that for each property, and there are heaps, I need to do the whole try catch block.

What I thought I might do is create an extension method which would do the whole block for me and all i'd need to pass in is the model property and the enumeration.

So I could do something like;

quickQuote.state = bindingContext.ValueProvider.GetModelValue("state", ...) etc.

Is this possible?

A: 

's ok, I got it.

public static class TryGetValueHelper
{
    public static TEnum TryGetValue<TEnum>(this ModelBindingContext context, string property)
    {
        try
        {
            TEnum propertyValue = (TEnum)Enum.Parse(typeof(TEnum), context.ValueProvider.GetValue(property).AttemptedValue);
            return propertyValue;
        }
        catch {
            ModelState modelState = new ModelState();
            ModelError modelError = new ModelError("Required");
            modelState.Errors.Add(modelError);
            context.ModelState.Add(context.ModelName + "." + property, modelState);
        }

        return default(TEnum);

    }
}
griegs
D'oh! Posted at the same time. Still, check out Enum.IsDefined if you want to get rid of the try/catch block.
Mac
+1  A: 

Yes you can have an extension method. Here's a very simple example to show how you'd write it.

public static class Extensions
{
    public static ValueProviderResult GetModel(this IValueProvider valueProvider, string key)
    {
        return valueProvider.GetValue(key);

    }
}

The other thing I'd consider is to use Enum.IsDefined rather than a try catch block. It will improve performance and probably result in more readable code.

Mac
+1 I did that, thanks very much.
griegs
I can't mark my own as the answer but yours is very good so...
griegs