Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save vickramravichandran/17a3326e44b14144b3e4b81643c59bff to your computer and use it in GitHub Desktop.
Save vickramravichandran/17a3326e44b14144b3e4b81643c59bff to your computer and use it in GitHub Desktop.
Custom DateTime Model Binding in ASP.NET Web API
public class DateTimeParameterAttribute : ParameterBindingAttribute
{
public string DateFormat { get; set; }
public bool ReadFromQueryString { get; set; }
public override HttpParameterBinding GetBinding(
HttpParameterDescriptor parameter)
{
if (parameter.ParameterType == typeof(DateTime?))
{
var binding = new DateTimeParameterBinding(parameter);
binding.DateFormat = DateFormat;
binding.ReadFromQueryString = ReadFromQueryString;
return binding;
}
return parameter.BindAsError("Expected type DateTime?");
}
}
public class DateTimeParameterBinding : HttpParameterBinding
{
public string DateFormat { get; set; }
public bool ReadFromQueryString { get; set; }
public DateTimeParameterBinding(HttpParameterDescriptor descriptor)
: base(descriptor) { }
public override Task ExecuteBindingAsync(
ModelMetadataProvider metadataProvider,
HttpActionContext actionContext,
CancellationToken cancellationToken)
{
string dateToParse = null;
string paramName = this.Descriptor.ParameterName;
if (ReadFromQueryString)
{
// reading from query string
var nameVal = actionContext.Request.GetQueryNameValuePairs();
dateToParse = nameVal.Where(q => q.Key.EqualsEx(paramName))
.FirstOrDefault().Value;
}
else
{
// reading from route
var routeData = actionContext.Request.GetRouteData();
object dateObj = null;
if (routeData.Values.TryGetValue(paramName, out dateObj))
{
dateToParse = Convert.ToString(dateObj);
}
}
DateTime? dateTime = null;
if (!string.IsNullOrEmpty(dateToParse))
{
if (string.IsNullOrEmpty(DateFormat))
{
dateTime = ParseDateTime(dateToParse);
}
else
{
dateTime = ParseDateTime(dateToParse, new string[] { DateFormat });
}
}
SetValue(actionContext, dateTime);
return Task.FromResult<object>(null);
}
public DateTime? ParseDateTime(
string dateToParse,
string[] formats = null,
IFormatProvider provider = null,
DateTimeStyles styles = DateTimeStyles.AssumeLocal)
{
string[] CUSTOM_DATE_FORMATS = new string[]
{
"yyyyMMddTHHmmssZ",
"yyyyMMddTHHmmZ",
"yyyyMMddTHHmmss",
"yyyyMMddTHHmm",
"yyyyMMddHHmmss",
"yyyyMMddHHmm",
"yyyyMMdd",
"yyyy-MM-ddTHH-mm-ss",
"yyyy-MM-dd-HH-mm-ss",
"yyyy-MM-dd-HH-mm",
"yyyy-MM-dd",
"MM-dd-yyyy"
};
if (formats == null)
{
formats = CUSTOM_DATE_FORMATS;
}
DateTime validDate;
foreach (var format in formats)
{
if (format.EndsWith("Z"))
{
if (DateTime.TryParseExact(dateToParse, format,
provider,
DateTimeStyles.AssumeUniversal,
out validDate))
{
return validDate;
}
}
if (DateTime.TryParseExact(dateToParse, format,
provider, styles, out validDate))
{
return validDate;
}
}
return null;
}
}
[RoutePrefix("api")]
public class MainController : ApiController
{
[Route("EchoDate/{date}")]
[HttpGet]
public DateTime? EchoDate(
[DateTimeParameter]
DateTime? date)
{
return date;
}
[Route("EchoCustomDate/{date}")]
[HttpGet]
public DateTime? EchoCustomDateFormat(
[DateTimeParameter(DateFormat = "dd_MM_yyyy")]
DateTime? date)
{
return date;
}
}
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// add the rule to the collection
config.ParameterBindingRules
.Add(typeof(DateTime?),
des => new DateTimeParameterBinding(des));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment