0

We are supposed to write an api that gives customer information,the url should be something like this

https://----.com/api/CustomerInfo/GetInfo?fromDate=1111&toDate=2222,.....

but instead of GetInfo,the client should call customer account number and if its a valid account, the account information should be returned, for example the client should call something like this

 https://----.com/api/CustomerInfo/98587445895?fromDate=1111&toDate=2222,.....

Where 98587445895 is customer account.
How should i get it to work in that way?

Abolfazl
  • 1,592
  • 11
  • 32

3 Answers3

0

You should follow the suggestions given by C.M. and Hogan to hide the action name.

For what concern, where your account number should be validated, it depends on your system architecture. If you, for example, would bind the route parameter to an int, the first level of format validation should be performed by the ASP.NET Web API binder. This is a really simple validation because it would fail only if the account number is not an int or if it exceeds the limit of the data type. For a more robust validation that is not dependent on the format of the data type, you could have a Service Layer where checks would be made to establish if that account number is valid taking into consideration your custom rules.

I hope my answers will be helpful. Let me know if you need more information.

claudiom248
  • 346
  • 2
  • 9
0

I Found it out finally...

We need to add an action selector and constraint to api config as follows:

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
      config.MapHttpAttributeRoutes();

      config.Routes.MapHttpRoute(
      name: "PayaApi",
      routeTemplate: "api/{controller}/{action}/{id}",
      defaults: new { id = RouteParameter.Optional },
      constraints: new { action = new AccountConstraint() });
      config.Services.Replace(typeof(IHttpActionSelector),
                               new PayaActionSelector());
    }
}

Our action selector would be something like this

public class PayaActionSelector : ApiControllerActionSelector
{
    public override HttpActionDescriptor SelectAction(HttpControllerContext context)
    {
        var actionMethod = context.ControllerDescriptor.ControllerType
         .GetMethods(BindingFlags.Instance | BindingFlags.Public).FirstOrDefault(x=>x.Name=="GetInfo");
        return new ReflectedHttpActionDescriptor(context.ControllerDescriptor, actionMethod);
    }
}

And where we check our account is here,Constraint

public class AccountConstraint : IRouteConstraint
{
    public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
    {
        var accList=Db.GetAccounts();
        object Account;
        values.TryGetValue("action", out Account);
        if (Account!=null && accList.Any(x=>x.AccNo==(string)Account))
        {                
            return true;
        }
        return false;
    }
}
Abolfazl
  • 1,592
  • 11
  • 32
-1

You can maintain it through route attributes. something like below syntax

[Route("api/CustomerInfo/98587445895/{fromDate}/{toDate}")]
Karan Ekkawala
  • 317
  • 1
  • 11