(C# ASP.NET Core) Customized Binding of API Parameters

Consider a web api that extracts parameters x, y and z from its query string and then uses these values to construct a Point object, say for example, by passing these data to a constructor of the Point class. This program can be made more readable by passing a single string of a comma separated list of three numbers, and then have that string directly parsed into a Point object. This technique of customized binding is the subject matter of this tutorial.
(Rev. 06-Nov-2022)

Categories | About |     |  

Parveen,

Decide on the format of query-string

Let us suppose the format of the data to be sent is a simple comma-separated list of numbers, and that it has to be sent through a query-string variable called p, as you are seeing here:


https://.../?p=1,2,3

Since this is a tutorial, I will keep the things simple. Otherwise a more readable format like a cartesian format of brackets could be more appropriate in a real project.

Video Explanation (see it happen!)

Please watch the following youtube video:

The class for conversion

Let's suppose that the above string has to be parsed and stored in a class called MyPoint. This class has 3 members to hold three co-ordinates x, y and z.


public class MyPoint
{
    public float x { get; set; }
    
    public float y { get; set; }

    public float z { get; set; }
}

Where should the code for parsing the querystring be written?

ASP.NET Core requires that this code should be added through a public static function called TryParse as you are seeing here.


public class MyPoint
{
    public float x { get; set; }
    
    public float y { get; set; }

    public float z { get; set; }

    public static bool TryParse(string? data, out MyPoint? p)
    {
        // ... code for parsing 
    }
}

The web api executes this function just at the time it receives the query string. The function receives the query string into the variable string? data. After that we can write suitable statements to split that string into x, y and z and return an instance of MyPoint. Let's see it practically!

Example Code

We have created a simple web api project to demonstrate this. The source code can be found in the downloads attached to this video.

Open the solution explorer and locate the MyPoint.cs file. Double click and open the file so that we can examine the code for this class.


namespace MyRazorApp.Models
{
    // model class 
    public class MyPoint
    {
        public float x { get; private set; }
        public float y { get; private set; }
        public float z { get; private set; }

        public static bool TryParse(string? data, out MyPoint? p)
        {
            p = new MyPoint();

            // extract comma separated: 1,2,3 
            string[]? xyz = data?.Split(',');

            int args = (null == xyz ? 0 : xyz.Length);

            p.x = ((args > 0) && float.TryParse(xyz?[0], out float _x)) ? _x : float.NaN;

            p.y = ((args > 1) && float.TryParse(xyz?[1], out float _y)) ? _y : float.NaN;

            p.z = ((args > 2) && float.TryParse(xyz?[2], out float _z)) ? _z : float.NaN;

            return true;

        }

    }
}

First of all this class has properties for the x, y and z co-ordinates.

After that we have the TryParse function. This function receives the comma separated string in a variable called data. The string is split into an array, and then the co-ordinates x, y and z are extracted. If a coordinate cannot be extracted then it is set as a NaN - not a number.

This function always returns true - so it is guranteed to succeed - format exceptions will not be thrown by the runtime. So we will have to check data integrity by inspecting each of the variables for a NaN value. Another approach could be to include a boolean data member to indicate data integrity.

Come to the solution explorer again and locate the program.cs file. Double to open this file, and scroll to the part that you are seeing here.

First notice that the API receives MyPoint without any attribute decoration. Secondly, the identifier p will automatically connect to the query-string variable p and make it available to the TryParse function. Customized parameter binding of MyPoint now occurs through its TryParse function.

If data integrity fails, we return HTTP 404 error.

Otherwise we echo back the extracted point.

Run the Project

Let's test the web api now! Run the project and send a GET request with a querystring parameter 1,2,3. We verify that the api echoes the co-ordinates back and responds as expected.

Next let us send a GET request of just 2 co-ordinates. We verify that the conversion fails and we get bad data HTTP 404 error. Thankyou!


This Blog Post/Article "(C# ASP.NET Core) Customized Binding of API Parameters" by Parveen is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.