Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Value tuples expose wrong parameter name from WebAPI

I'm using web api. I've been a bit lazy and decided to return a value tuple from my controller.

[HttpGet]
[Route(AuthAPIRoutes.GET_MFA_DEVICES)]
public (string Type, string Value)[] GetMultiFactoryMethods()
{
    return GlobalFactory<IPaystreamMFASecurityService>.Instance.GetMultiFactorMethods();
}

The JSON response doesn't seem to be using the appropriate naming is this being optimized away?

{
    "item1": "Phone",
    "item2": "1-512-555-0550"
}

NOTE: I'm aware I can explicitly make a model to avoid this problem. I would like to understand what is occurring and why aren't my value tuple names being respected in the response?

like image 700
johnny 5 Avatar asked Jun 17 '19 19:06

johnny 5


People also ask

How do I pass body parameters in Web API?

Use [FromUri] attribute to force Web API to get the value of complex type from the query string and [FromBody] attribute to get the value of primitive type from the request body, opposite to the default rules.

What is FromBody and FromUri in Web API?

The [FromUri] attribute is prefixed to the parameter to specify that the value should be read from the URI of the request, and the [FromBody] attribute is used to specify that the value should be read from the body of the request.

What is FromBody in C#?

The [FromBody] attribute which inherits ParameterBindingAttribute class is used to populate a parameter and its properties from the body of an HTTP request. The ASP.NET runtime delegates the responsibility of reading the body to an input formatter.


1 Answers

What is occurring is that ValueTuple as a type (a group of generic types, actually) is actually very static, and has properties named things like Item1, Item2, etc.

The nice syntax you get from C# where you can declare a name and have it used elsewhere in your code is simply a feature of the C# language. The compiled code referencing those values by name ends up calling into those static properties (Item1, e.g.). And in fact, you can still access those properties by their "Item" names in your own C# code.

From the compiled code's perspective, the only clue about the names of the fields on those tuples is an attribute that gets associated with the method, so unless ASP.NET passed contextual information about the action method into the serializer, there would be no way for the serializer to know what names those properties were supposed to have.

See this article for an in-depth look at what ValueTuples are doing under the hood.

like image 91
StriplingWarrior Avatar answered Nov 14 '22 23:11

StriplingWarrior