• Home
  • About
  • Contact
  • ado.net
  • angular
  • c#.net
  • design patterns
  • linq
  • mvc
  • .net core
    • .Net Core MVC
    • Blazor Tutorials
  • sql
  • web api
  • dotnet
    • SOLID Principles
    • Entity Framework
    • C#.NET Programs and Algorithms
  • Others
    • C# Interview Questions
    • SQL Server Questions
    • ASP.NET Questions
    • MVC Questions
    • Web API Questions
    • .Net Core Questions
    • Data Structures and Algorithms

Saturday, July 4, 2020

Web API Attribute Routing Route Constraints

 Admin     July 04, 2020     .Net, Asp.Net, C#, Web API     No comments   

In this article, I will discuss the Web API Attribute Routing Route Constraints with examples. We are going to work with the same example that we worked in our previous articles. So, please read the following articles before proceeding to this article.
  1. Attribute Routing in Web API
  2. Optional URI Parameters and Default values in Attribute Routing
  3. Attribute Routing Route Prefix in WEB API
Web API Attribute Routing Route Constraints
The Web API Attribute Routing Route Constraints are nothing but a set of rules that we can apply on our routing parameters to restrict how the parameters in the route template are matched. The general syntax is

{parameter:constraint}

Let us understand ASP.NET Web API Attribute Routing Route Constraints with one example.
Let’s modify the Students Controller as shown below.
namespace AttributeRoutingInWEBAPI.Controllers
{
    [RoutePrefix("students")]
    public class StudentsController : ApiController
    {
        static List<Student> students = new List<Student>()
        {
            new Student() { Id = 1, Name = "Pranaya" },
            new Student() { Id = 2, Name = "Priyanka" },
            new Student() { Id = 3, Name = "Anurag" },
            new Student() { Id = 4, Name = "Sambit" }
        };
        [HttpGet]
        [Route("{studentID}")]
        public Student GetStudentDetails(int studentID)
        {
            Student studentDetails = students.FirstOrDefault(s => s.Id == studentID);
            return studentDetails;
        }
    }
}
Now, if we navigate to /students/1 URI, then the GetStudentDetails(int studentID) action is executed and we get the details of the student whose id is 1 as expected.

Let’s change our business requirement, in addition to retrieving the student details by “student Id”, we also want to retrieve the student details by “student Name“. So let’s add another GetStudentDetails() action method with a string parameter as shown below.
namespace AttributeRoutingInWEBAPI.Controllers
{
    [RoutePrefix("students")]
    public class StudentsController : ApiController
    {
        static List<Student> students = new List<Student>()
        {
            new Student() { Id = 1, Name = "Pranaya" },
            new Student() { Id = 2, Name = "Priyanka" },
            new Student() { Id = 3, Name = "Anurag" },
            new Student() { Id = 4, Name = "Sambit" }
        };
        [HttpGet]
        [Route("{studentID}")]
        public Student GetStudentDetails(int studentID)
        {
            Student studentDetails = students.FirstOrDefault(s => s.Id == studentID);
            return studentDetails;
        }
        [HttpGet]
        [Route("{studentName}")]
        public Student GetStudentDetails(string studentName)
        {
            Student studentDetails = students.FirstOrDefault(s => s.Name == studentName);
            return studentDetails;
        }
    }
}
At this point build the solution, and navigate to the following URI’s

/students/1

/students/Pranaya

In both the cases we will get the below error:
Multiple actions were found that match the request: GetStudentDetails on type AttributeRoutingInWEBAPI.Controllers.StudentsController GetStudentDetails on type AttributeRoutingInWEBAPI.Controllers.StudentsController

This is because the WEB API Framework does not know or does not identify which version of the GetStudentDetails() action method to use. This is the situation where the route constraints play a very important role.

If an integer is specified in the URI like /students/1, then we need to execute the GetStudentDetails(int studentId) action method which takes an integer parameter whereas if a string is specified in the URI like /students/Pranaya, then we need to execute the GetStudentDetails(string studentName) action method which takes the parameter of type string.

This can be very easily achieved using Attribute Route Constraints in the WEB API application. To specify the attribute route constraint, the syntax is “{parameter:constraint}“. With these constraints in place, if the parameter segment in the URI is an integer, then the GetStudentDetails(int studentId) action method with integer parameter is invoked and if it is a string value then the GetStudentDetails(string studentName) action method with string parameter is invoked.

Let’s modify the Student Controller to use the Attribute Route Constraints as shown below to achieve the above requirements.
namespace AttributeRoutingInWEBAPI.Controllers
{
    [RoutePrefix("students")]
    public class StudentsController : ApiController
    {
        static List<Student> students = new List<Student>()
        {
            new Student() { Id = 1, Name = "Pranaya" },
            new Student() { Id = 2, Name = "Priyanka" },
            new Student() { Id = 3, Name = "Anurag" },
            new Student() { Id = 4, Name = "Sambit" }
        };
        [HttpGet]
        [Route("{studentID:int}")]
        public Student GetStudentDetails(int studentID)
        {
            Student studentDetails = students.FirstOrDefault(s => s.Id == studentID);
            return studentDetails;
        }
        [HttpGet]
        [Route("{studentName:alpha}")]
        public Student GetStudentDetails(string studentName)
        {
            Student studentDetails = students.FirstOrDefault(s => s.Name == studentName);
            return studentDetails;
        }
    }
}
Now build the solution, and navigate to the following two URIs and see everything is working as expected.

/students/1

/students/Pranaya

Please note that “alpha” stands for uppercase or lowercase alphabet characters. Along with alpha and int, you can also use constraints such as decimal, float, long, double, bool, etc. Please check the following MSDN link for the full list of available constraints in web API.
https://docs.microsoft.com/en-us/aspnet/web-api/overview/web-api-routing-and-actions/attribute-routing-in-web-api-2#route-constraints
Example:
If you want GetStudentDetails(int studentId) action method to be mapped to URI /students/{studentId}, only if the studentId is a number greater than ZERO, then use the “min” constraint as shown below.
WEB API Route Constraints in Attribute Routing

With the above change, if we specify a positive number like 1 in the URI, then it will be mapped to the GetStudentDetails(int studentID) action method as expected

/students/1

However, if we specify 0 or a negative number less than ZERO, then we will get an error. For example, if we specify 0 as the value for studentID in the URI,

/students/0

We will get the below error
WEB API Route Constraints in Attribute Routing

Along with the “min” constraint, you can also specify the “max” constraint as shown below. For example, if you want the studentID value in the URI to be between 1 and 3 inclusive, then you can specify both “min” and “max” constraints as shown below.
WEB API Route Constraints in Attribute Routing

The above example can also be achieved using the “range” attribute as shown below
WEB API Route Constraints in Attribute Routing

Custom Web API Route Constraints in Attribute Routing
You can also create custom route constraints in Web API and to do so you need to implement the IHttpRouteConstraint interface. For example, the below constraint will restrict a parameter value to a non-zero integer value.
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Net.Http;
using System.Web.Http.Routing;
namespace AttributeRoutingInWEBAPI.Models
{
    public class NonZeroConstraint : IHttpRouteConstraint
    {
        public bool Match(HttpRequestMessage request, IHttpRoute route, string parameterName,
            IDictionary<string, object> values, HttpRouteDirection routeDirection)
        {
            object value;
            if (values.TryGetValue(parameterName, out value) && value != null)
            {
                long longValue;
                if (value is long)
                {
                    longValue = (long)value;
                    return longValue != 0;
                }
                string valueString = Convert.ToString(value, CultureInfo.InvariantCulture);
                if (Int64.TryParse(valueString, NumberStyles.Integer,
                    CultureInfo.InvariantCulture, out longValue))
                {
                    return longValue != 0;
                }
            }
            return false;
        }
    }
}
The following code shows how to register the custom constraint:
namespace AttributeRoutingInWEBAPI
{
    public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            var constraintResolver = new DefaultInlineConstraintResolver();
            constraintResolver.ConstraintMap.Add("nonzero", typeof(NonZeroConstraint));
            // Attribute routing.
            config.MapHttpAttributeRoutes(constraintResolver);
            // Convention-based routing.
            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );
        }
    }
}
Now you can apply the custom constraint in your routes as shown below.
[HttpGet]
[Route("{studentName:alpha}")]
public Student GetStudentDetails(string studentName)
{
    Student studentDetails = students.FirstOrDefault(s => s.Name == studentName);
    return studentDetails;
}
In the next article, I am going to discuss Route Names and Route Orders in WEB API. Here, in this article, I try to explain the Web API Attribute Routing Route Constraints with examples. I hope this Web API Attribute Routing Route Constraints article will help you with your needs. I would like to have your feedback. Please post your feedback, question, or comments about this article.

Summary:
I Hope this post will be helpful to understand the concept of Web API Attribute Routing Route Constraints
Please share this post with your friends and colleagues.
For any queries please post a comment below.
Happy Coding 😉
  • Share This:  
  •  Facebook
  •  Twitter
  •  Google+
  •  Stumble
  •  Digg
Newer Post Older Post

0 comments:

Post a Comment

If you like this website, please share with your friends on Facebook, Twitter, LinkedIn.

Join us on Telegram

Loved Our Blog Posts? Subscribe To Get Updates Directly To Your Inbox

Like us on Facebook

Popular Posts

  • What is Dependency Injection(DI)
    Hi friends! Today we are going to learn about Dependency Injection and in our last session we have come across Static classes and where it s...
  • C# Programming Examples on Sorting
    Today i am going to tell you some of the Sorting programming questions in C#. Q1- Write a C# program to perform Selection sort. Ans:  Sel...
  • Calling Web API Service in a Cross-Domain Using jQuery AJAX
    In this article, I am going to discuss Calling Web API Service in a Cross-Domain Using jQuery AJAX . Please read our previous article befor...
  • ViewBag in ASP.NET Core MVC
    In this article, I am going to discuss the use of ViewBag in ASP.NET Core MVC application with examples. Please read our previous article ...
  • Recursion And Back Tracking
    In this article, I am going to discuss Recursion And BackTracking in detail. Please read our previous article where we discussed Master Th...
  • What is Abstract Class and When we should use Abstract Class
    Hi friends! In our previous sessions we have seen  Difference Between Class and Struct . And in our last session  we learnt Usability of Sec...
  • Binary to Decimal Conversion in C# with Examples
    In this article, I am going to discuss the Binary to Decimal Conversion in C# with some examples. Please read our previous article where w...

Blog Archive

Contact Form

Name

Email *

Message *

Tags

.Net .Net Core .Net Core MVC Algorithm Angular Anonymous Types Asp.Net Asp.Net MVC Blazor C# Data Structure Database Design Patterns Entity Framework Entity Framework Core Filters Interview Question Management Studio Programming Programs SQL Server SSMS Web API

Copyright © C# Techtics | All Right Reserved.

Protected by Copyscape