'how to check if DTO has the expected data types in .net?

i have a webapi done in .net. I would like to verify the data the user inserts has the expected data type. Here is my DTO:

    public class EditHash
{
    public EditHash()
    {
    }
    public string? UrlShort { get; set; }
    public string? UrlOrigin { get; set; }
    public DateTime ExpireAt { get; set; }
}

and here is how i tried to verify the data type :

        public async Task<IActionResult> ModifyUrl(string hash, [FromBody] Request.EditHash h )
    {
if(!(h.ExpireAt is DateTime) ||  !(h.UrlShort is string))
        {
            gc.errorNumber = "505";
            gc.value = "Bad Request";
            gc.detail = "One or many parameters data type are not correct";
            return new TimeoutExceptionObjectResult(error: gc, 400);
        }
    }

i also tried with this method :

if(h.ExpireAt.GetType()!=typeof(DateTime) || h.UrlOrigin.GetType()!=typeof(string) ||h.UrlShort.GetType()!= typeof(string))
        {
            ...
        }

in the both cases, when i insert an integer instead of a string for instance, the code does not returns the error i defined. How can i verify the data type ?



Solution 1:[1]

If you expect the user can call your API (and get a controlled response) with 'incorrect' values; you need a more 'permissive' data structure as input then you can check the values an cast to the real DTO:

public class EditHash_Permissive_Input
{
    public string UrlShort { get; set; }
    public string UrlOrigin { get; set; }
    public string ExpireAt { get; set; }
}

Then in the exposed method:

public async Task<IActionResult> ModifyUrl(string hash, [FromBody] Request.EditHash_Permissive_Input h )
{
if(!DateTime.TryParse(h.ExpireAt, out DateTime dateTimeInput) || String.IsNullOrEmpty(h.UrlShort)) //<- Add other desired validations to url as "1" is a string and could not be a valid url
    {
        gc.errorNumber = "505";
        gc.value = "Bad Request";
        gc.detail = "One or many parameters data type are not correct";
        return new TimeoutExceptionObjectResult(error: gc, 400);
    }
    else
    {
         Request.EditHash internalValue = new Request.EditHash() 
            {
                UrlShort = h.UrlShort,
                UrlOrigin = h.UrlOrigin,
                ExpireAt = dateTimeInput,
            }
         //Continue with what you mean to do with h data
    }
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 J.Salas