Introduction
In this short discussion, we are going to understand Route Constraints in Web API. As this is a short content article, our main focus will be on the description of Route Constraints.
At the end of the discussion, we will create a Custom Route Constraints.
What are Route Constraints?
Before going to discuss about Route Constraints, let's take a look into attribute routing. In a very short version, routing is nothing but a way to use our Web API matches a URI to an action.
In the new version of Web API, i.e., Web API2, there is a new type of routing which is named as attribute routing.
In attribute routing, we define attributes to create route. With the use of this, one can define the hierarchy of resources of API and it's easy to handle/control.
Take a look into a few code-snippets:
[Route("serverdata/{type}")]
public IEnumerable<ServerData> GetServerData(int type)
{
return ServerDataRepository.GetAll().Where(d => d.Type == type);
}
[Route("serverdata/{zone}")]
public IEnumerable<ServerData> GetServerData(string zone)
{
}
In this manner, we can easily define the URI pattern and manage/handle our resources.
Now, imagine you have such a complex or long URI, where you can use your parameter in any type (like int
or string
), refer to the following code-snippet as an example:
[Route("serverdata/{type}/datadetails")]
public IEnumerable<DataDetail> GetDataDetailsByType(int type)
{
}
Now, whenever a request comes,Web API tried to match URI "serverdata/{type}/datadetails" template defined in route. We can pass different values to make this template valid:
How It Works?
In the above URI route template, our {type} is a parameter (I often called it as URI placeholder), when we pass the value it automatically assigns the same to our action method's parameter.
Imagine where we are passing "external" in URI template, our template matches but actually our parameter is int
. You can imagine what is wrong here?
Here, we reached at our main discussion Route Constraints in Web API, this is nothing but provides a facility to restrict parameters so, Web API match correct URI route template.
In route, we just need to define a constraint with the parameter, e.g.,"{parameter:constraint}
".
Mostly Available/Used Constraints
Here, I try to include almost all route constraints:
int
constraints - restricts to 32-bit integer value
[Route("serverdata/{typeid:int}")]
public IEnumerable<ServerData> GetServerDataByType(int typeid)
{
}
double
constraints - restricts to 64-bit floating value
[Route("serverdata/{typeconst:double}")]
public ServerData GetCalculatedDataFrequency(double typeconst)
{
}
float
constraints - restricts to 32-bit floating value
[Route("serverdata/{typeconst:float}")]
public ServerData GetCalculatedDataFrequency(float typeconst)
{
}
Note: I suggest, try double and float constraints
guid
constraints - restricts to GUID value
[Route("serverdata/{id:guid}")]
public ServerData GetServerDataById(Guid id)
{
}
length
constraints - restricts string
to specified length or specified length range
[Route("serverdata/{passcode:length(8)}")]
public String GetDatabasename(string passcode)
{
}
[Route("serverdata/{passcode:length(4,18)}")]
public String GetDatabasename(string passcode)
{
}
long
constraints - restricts to 64-bit integer value
[Route("serverdata/{typeid:long}")]
public IEnumerable<ServerData> GetServerDataByType(long typeid)
{
}
alpha
constraints - restricts to upper/lower case english alphabets
[Route("serverdata/{spname:alpha}")]
public IEnumerable<ServerData> GetServerDataByType(string spname)
{
}
bool
constraints - restricts to boolean value (true
/false
)
[Route("serverdata/{isDeleted:bool}")]
public IEnumerable<Records> GetDeletedRecords(bool isDeleted)
{
}
datetime
constraints - restricts to DateTime value
[Route("serverdata/{createdon:datetime}")]
public IEnumerable<Records> GetRecordsoByCreatedDate(DateTime createdon)
{
}
decimal
constraints - restricts to decimal value
[Route("serverdata/{amount:decimal}/employee")]
public IEnumerable<EmployeeData> GetEmployeebySalary(Decimal amount)
{
}
range
constraints - restricts an integer within a range of value
[Route("serverdata/{typeid:range(3,15)}")]
public IEnumerable<EmployeeData> GetEmployeebyType(int typeid)
{
}
Apart from the above, there are few more like regex
, maxlength
, minlength
, I am not going to discuss about these as these are as clear as their names.
Creating Custom Route Constraints
There are many Route constraints available (as discussed in the preceding code), but there might be scenarios, where we need some special kind of constraints. To fulfill those requirements, we can create our own constraints.
In the very first step for creation of Custom Route Constraints, we need to implement interface IHttpRouteConstraint
.
I am taking an example of my live project where we have to restrict bad-words:
The following code-snippet depicts custom constraints:
public class NoBadWordsConstraint : IHttpRouteConstraint
{
public bool Match(HttpRequestMessage request, IHttpRoute route, string parameterName,
IDictionary<string, object> values, HttpRouteDirection routeDirection)
{
object value;
string[] badWords=new string[]{"bad1","bad2","bad3"};
if (values.TryGetValue(parameterName, out value) && value != null)
{
string stringValue;
if (value is string)
{
stringValue = (string)value;
foreach(var w in badWords)
{
if(w.Contains(stringValue)) return false;
}
return true;
}
}
return false;
}
}
To use this, we have to tell Web API2 that it exists, so we need to register it first. Add the following lines in your WebApiConfig
class in Register
method.
var defaultconstraintResolver = new DefaultInlineConstraintResolver();
defaultconstraintResolver.ConstraintMap.Add("nobadword", typeof(NoBadWordsConstraint));
config.MapHttpAttributeRoutes(defaultconstraintResolver);
Following is the code-snippet, showing how we can use it:
[Route("serverdata/{word:length(10)}")]
public IEnumerable<EmployeeData> GetEmployeebyword(string word)
{
}
Closing Notes
In this short content article, we discussed Route constraints, types of constraints and finally, we created a custom constraint.
The post Discussing Web API2 Route Constraints appeared first on Gaurav-Arora.com.