Skip to content

Instantly share code, notes, and snippets.

@stevenharman
Created November 2, 2010 19:25
Show Gist options
  • Save stevenharman/660144 to your computer and use it in GitHub Desktop.
Save stevenharman/660144 to your computer and use it in GitHub Desktop.
an asp.net-mvc Model Binder that respects the ISO 8601 standard. look it up, yo!
using System;
using System.Globalization;
using System.Web.Mvc;
namespace Zomg.Web.ModelBinders
{
public class Iso8601DateTimeBinder : DefaultModelBinder
{
public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
var name = bindingContext.ModelName;
var value = bindingContext.ValueProvider.GetValue(name);
if (value == null) return null;
return parseIso8601Date(value) ?? base.BindModel(controllerContext, bindingContext);
}
private DateTime? parseIso8601Date(ValueProviderResult value)
{
DateTime date;
return DateTime.TryParseExact(value.AttemptedValue, "o", null, DateTimeStyles.RoundtripKind, out date) ? date : null as DateTime? ;
}
}
}
using System;
using System.Collections.Specialized;
using System.Web.Mvc;
using Zomg.Specs.Infrastructure;
using Zomg.Web.ModelBinders;
namespace Specs_for_Iso8601DateTimeBinder
{
public class when_binding_to_an_iso_8601_datetime_string : Concerns
{
private DateTime _realDate;
private DateTime? _boundDate;
protected override void Context()
{
_realDate = new DateTime(1981, 04, 28, 15, 32, 51, 147, DateTimeKind.Utc);
var fields = new NameValueCollection { { "somedate", "1981-04-28T15:32:51.1470000Z" } };
var metaCrap = ModelMetadataProviders.Current.GetMetadataForType(null, typeof(DateTime?));
var binderContext = new ModelBindingContext
{
ModelName = "somedate",
ModelMetadata = metaCrap,
ValueProvider = new NameValueCollectionValueProvider(fields, null)
};
_boundDate = new Iso8601DateTimeBinder().BindModel(new ControllerContext(), binderContext) as DateTime?;
}
[Specification]
public void bind_it()
{
_boundDate.ShouldEqual(_realDate).And().Value.Kind.ShouldEqual(DateTimeKind.Utc);
}
}
public class when_binding_to_a_non_iso_8601_datetime_string : Concerns
{
private DateTime _realDate;
private DateTime? _boundDate;
protected override void Context()
{
_realDate = new DateTime(1981, 04, 28, 15, 32, 51, 147, DateTimeKind.Utc);
var fields = new NameValueCollection { { "somedate", "1981-04-28T15:32:51.147" } };
var metaCrap = ModelMetadataProviders.Current.GetMetadataForType(null, typeof(DateTime?));
var binderContext = new ModelBindingContext
{
ModelName = "somedate",
ModelMetadata = metaCrap,
ValueProvider = new NameValueCollectionValueProvider(fields, null)
};
_boundDate = new Iso8601DateTimeBinder().BindModel(new ControllerContext(), binderContext) as DateTime?;
}
[Specification]
public void fall_back_to_default_datetime_binding()
{
_boundDate.ShouldEqual(_realDate).And().Value.Kind.ShouldEqual(DateTimeKind.Unspecified);
}
}
public class when_binding_to_a_non_datetime_string : Concerns
{
private DateTime? _boundDate;
protected override void Context()
{
var fields = new NameValueCollection { { "somedate", "ZOMG:123" } };
var metaCrap = ModelMetadataProviders.Current.GetMetadataForType(null, typeof(DateTime?));
var binderContext = new ModelBindingContext
{
ModelName = "somedate",
ModelMetadata = metaCrap,
ValueProvider = new NameValueCollectionValueProvider(fields, null)
};
_boundDate = new Iso8601DateTimeBinder().BindModel(new ControllerContext(), binderContext) as DateTime?;
}
[Specification]
public void fall_back_to_default_datetime_binding()
{
_boundDate.ShouldBeNull();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment