ibubi
ibubi

Reputation: 2549

http get method does not supported when using datetime parameter

I have Webapi service controller that supports two get method which distincts by parameter

Controller

public class DailyRecordController : BaseApiController
{
    private IDailyBroadcastRepository _repo;

    public DailyRecordController(IDailyBroadcastRepository repo)
    {
        _repo = repo;
    }
    public IQueryable<DailyBroadcast> Get(DateTime? date=null)
    {
        var dailyBroadcastList = new List<DailyBroadcast>();
        try
        {
            dailyBroadcastList = _repo.GetDailyBroadcastByDate(date??DateTime.Now).ToList();
        }
        catch (Exception ex)
        {
            //Log
        }
        return dailyBroadcastList.AsQueryable();
    }

    public DailyBroadcast Get(int? Id)
    {
        var dailyBroadcast = new DailyBroadcast();
        try
        {
            dailyBroadcast = _repo.GetDailyBroadcastById(Id);
        }
        catch (Exception ex)
        {
            //Log
        }
        return dailyBroadcast;
    }
}

Config

config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );

When call api/DailyRecord/2017-06-01 it hits to method with id:integer method, never hits the method with datetime parameter.

I have also tried to route attribute but not affected.

[HttpGet]
[Route("{date:datetime}")]

I fact, when I commnet out the second method with id parameter, the service returns
The requested resource does not support http method 'GET'
How can I build this controller with two Get methods that supports both datetime and integer parameters?

Upvotes: 1

Views: 772

Answers (2)

ibubi
ibubi

Reputation: 2549

I have solved the issue by implementing a route constraint as shown in this walkthrough

The route is restricted to the desired format by adding a regular-expression constraint to the route template:

[HttpGet]
[Route("{date:datetime:regex(\\d{4}-\\d{2}-\\d{2})}")]
public IQueryable<DailyBroadcast> GetByDate(DateTime date) {
    //...
}

Now only dates in the form "yyyy-mm-dd" will match. Notice that we don't use the regex to validate that we got a real date. That is handled when Web API tries to convert the URI segment into a DateTime instance. An invalid date such as '2012-47-99' will fail to be converted, and the client will get a 404 error.

Upvotes: 1

Brian Mains
Brian Mains

Reputation: 50728

Define 1 get method with a string input and use TryParse to verify the input is entered in the correct format.

Get(string val)
{
   DateTime dt, int id;
   if (DateTime.TryParse(val, out dt))
   {
      //Filter by date
   }
   else if (int.TryParse(val, out id))
   {
      //Filter by int
   }
   else
   {
      //Error state
   }
}

Upvotes: 1

Related Questions