Input date to webapi

646 views Asked by At

I am using webapi2. I have a property in model is start date whose datatype is datetime. I want to pass the date as "dd-mm-yyyy" format. But if i send, i am getting 400 bad request. Could you please help me out. Note, I am using Fluent validation for the model validation.

public class Item      
{
    public  DateTime? StartDate { get; set; }
    public  string Id { get; set; }
}
2

There are 2 answers

1
Igor On

I want to pass the date as "dd-mm-yyyy"`

You have 3 options.

Option ISO8601

Don't pass it as "dd-mm-yyyy". Pass it instead in ISO8601 format (yyyy-MM-dd). That is the correct way to serialize DateTimes to string and also for then communicating that string representation between tiers. This format is a standard, widely used, unambiguous, and almost all frameworks that I am aware of have built in mechanisms for outputting DateTimes to that format and parsing them from that format.

Displaying a DateTime formatted as "dd-mm-yyyy" is a presentation layer concern and it should stay there and not "bleed" into the other application layers.

Option Formatters

Use custom code, like a Json Converte or an ActionFilterAttribute, to read the incoming DateTime.

Option String

Accept a string parameter instead and handle your own parsing inside the controller's method.


I honestly do not recommend the last 2 options. Instead use ISO8601: a standard, unambiguous, widely accepted means of communicating a DateTime.

0
thegautamnayak On

I have created a custom value provider factory and am using the default model binding.

public class OrderValueProviderFactory<T> : ValueProviderFactory where T : class
    {
        public override IValueProvider GetValueProvider(HttpActionContext actionContext)
        {
            var querystring = actionContext.Request.GetQueryNameValuePairs().ToDictionary(x => x.Key.ToLower(), x => x.Value);
            return new OrderValueProvider<T>(querystring);
        }
    }
    public class OrderValueProvider<T> : IValueProvider
    {
        readonly Dictionary<string, string> querystring;

        public OrderValueProvider(Dictionary<string, string> _querystring)
        {
            querystring = _querystring;
        }
        public bool ContainsPrefix(string prefix)
        {
            return true;
        }

        public ValueProviderResult GetValue(string key)
        {
            T obj = (T)Activator.CreateInstance(typeof(T));
            PropertyInfo[] properties = typeof(T).GetProperties();
            foreach (var property in properties)
            {
                if (property.PropertyType == typeof(string))
                {
                    property.SetValue(obj, querystring.GetStringValue(property.Name.ToLower()));
                }
                else if (property.PropertyType == typeof(DateTime?))
                {
                    property.SetValue(obj, querystring.GetDateTimeValue(property.Name.ToLower()));
                }
                else if (property.PropertyType == typeof(int))
                {
                    property.SetValue(obj, querystring.GetIntValue(property.Name.ToLower()));
                }
            }
            return new ValueProviderResult(obj, "", CultureInfo.InvariantCulture);
        }
    }