In this blog, I will discuss about the inline-constrain for attributeRoute and also will discuss about default inline constrain and custom constrain.
Few days backed, I designed a API route for one Undo Web API method and
I tried to apply ENUM datatype validation on action in route and encountered below DefaultInlineConstrainResolver
Error
Error: System.InvalidOperationException: 'The inline constraint resolver of type 'DefaultInlineConstraintResolver' was unable to resolve the following inline constraint: 'ActionEnum’
[HttpGet]
[Route("api/orders/undo/{orderID}/action/{actiontype: OrderCorrectionActionEnum}")]
public IHttpActionResult Undo(int orderID, OrderCorrectionActionEnum actiontype)
{
_route(undo(orderID, action);
}
public enum OrderCorrectionActionEnum
{
[EnumMember]
Cleared,
[EnumMember]
Deleted,
}
By default Web API supports only few inline constrains
1.
Type-specific
constraints – support only primitive data type (except string)
{ "bool", typeof(BoolRouteConstraint)
},
{ "datetime", typeof(DateTimeRouteConstraint)
},
{ "decimal", typeof(DecimalRouteConstraint)
},
{ "double", typeof(DoubleRouteConstraint)
},
{ "float", typeof(FloatRouteConstraint)
},
{ "guid", typeof(GuidRouteConstraint)
},
{ "int", typeof(IntRouteConstraint)
},
{ "long", typeof(LongRouteConstraint)
},
2. Length constraints -
{ "minlength", typeof(MinLengthRouteConstraint)
},
{ "maxlength", typeof(MaxLengthRouteConstraint)
},
{ "length", typeof(LengthRouteConstraint)
},
3. Min/Max value constraints
{ "min", typeof(MinRouteConstraint)
},
{ "max", typeof(MaxRouteConstraint)
},
{ "range", typeof(RangeRouteConstraint)
},
4. Regex-based constraints
{ "alpha", typeof(AlphaRouteConstraint)
},
{ "regex", typeof(RegexRouteConstraint)
}
To apply ENUM constrain, you have to create custom OrderCorrectionEnumRouteConstraint
by using IHttpRouteConstraint.
public class OrderCorrectionEnumRouteConstraint : IHttpRouteConstraint
{
public bool Match(HttpContextBase httpContext, Route
route, string parameterName,
RouteValueDictionary values, RouteDirection routeDirection)
{
// You can also try Enum.IsDefined, but
docs say nothing as to
// is it case sensitive or not.
var response = Enum.GetNames(typeof(OrderCorrectionActionEnum)).Any(s => s.ToLowerInvariant()
== values[parameterName].ToString().ToLowerInvariant());
return response;
}
public bool Match(HttpRequestMessage request, IHttpRoute
route, string parameterName,
IDictionary<string, object> values, HttpRouteDirection routeDirection)
{
bool response = Enum.GetNames(typeof(BlockCorrectionActionEnum)).Any(s
=> s.ToLowerInvariant() ==
values[parameterName].ToString().ToLowerInvariant());
return response;
}
}
In Web API config, You
have to add this constrain
public static void
Register(HttpConfiguration config)
{
// Web API configuration and services
config.Services.Replace(typeof(IExceptionHandler), new
APIExceptionHandler());
// Web API Handler
// config.MessageHandlers.Add(new
APIAuthenticationHandler());
config.Filters.Add(new
APIClientTokenValidation());
var constraintsResolver = new
DefaultInlineConstraintResolver();
constraintsResolver.ConstraintMap.Add("OrderCorrectionActionEnum", typeof(OrderCorrectionEnumRouteConstraint));
// Web API routes
config.MapHttpAttributeRoutes(constraintsResolver);
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id =
RouteParameter.Optional }
);
}
You can also create generic ENUM constraints, which will be
applicable for all ENUM.
Thanks for visiting!!
Thanks for visiting!!