1

I have to build a .NET Core REST API and I have about two dozen endpoints that take in simple JSON objects like:-

{
  "foo": 23,
  "bar": "bar_value"
}

and

{
  "foo": 12,
  "baz": true
}

etc.

Some properties, such as foo above, are common among several endpoints but have different validation requirements. In some endpoints they are required, in others, they are not and so on. I can't change these JSON payloads as they're generated by a third party I don't have any control over.

How can I map these parameters to endpoints in a .NET Core API method directly, without a class?

I can, of course, create a class for each endpoint, such as

public class SomeObject
{
    [Required]
    [Range(0, 100)]
    public int? Foo { get; set; }
    
    public string bar { get; set; }
}


public class SomeOtherObject
{
    public int? Foo { get; set; }
    
    [Required]
    public bool Baz { get; set; }
}

...

Note the different validation rules.

But I don't feel like creating some two dozen classes. I'd much rather just specify them directly in the endpoint method:

[HttpPut]
[Route("/some-route")]
public IActionResult SomeAction([Required, Range(0, 100)] int? foo, byte? bar)
{
    ...
}

[HttpPut]
[Route("/some-other-route")]
public IActionResult SomeOtherAction(int? foo, [Required] baz)
{
    ...
}

It would be much easier to read and figure out which property is required and when by just looking at the methods instead of opening one of two dozen similarly named class files or opening one single file with two dozen similarly named classes with properties of the same name.

So how can I get .NET Core to parse the JSON and assign the property values to the action method parameters?

1 Answer 1

1

I'm not aware of a direct answer to this question as specified, so I'll answer this with an alternative approach as an XY problem based on your statement "It would be much easier to read and figure out which property is required and when by just looking at the methods".

This assumes there's not an easy way document your own API surface area if you're using classes. In your example, you're already writing a large amount of logic in the method signature itself, not to mention potential behaviors for default values, etc., that can make those signatures progressively harder to read and understand, and that's exactly what input model classes and model validation are designed to help encapsulate. Furthermore, now that you've decomposed the model into its parts, it becomes increasingly complex to handle validation issues as a cohesive model, regardless of whether it could be done. By accepting the entire object at once, you can run a ModelState.IsValid check, aggregate errors, or add your own and quickly return that from the controller.

By adding XML documentation to your endpoint methods and input model classes, you also open up the easy path of adding a Swagger page with Swashbuckle, which will provide a simple way for you to inspect what the model value types are and which ones are required, etc., as well as example JSON bodies in the Swagger page itself with full documentation as to the purpose of all the parameters.

While you do end up with a bunch of model classes, it's just a button press away from Visual Studio to hop to your class and see your validation requirements and input types while "in code". If class generation is frustrating, you can quickly drop your JSON samples into a class generator online and get a "pretty good" starting point for the input models: https://json2csharp.com/

Sign up to request clarification or add additional context in comments.

1 Comment

I agree with most of what you say and I do indeed use models for the rest of the API, but I simply find it easier to look at the method signature for these simple examples. I've upvoted your answer since you describe the better practice, but I won't mark it as correct just yet since it doesn't actually answer the question, not the way I worded it at least. By the way, you probably already know that Visual Studio (not code) has the option to paste copied JSON as C# code. It won't generate separate files, but I guess it might help if you're worried of leaking corpo code by using a website.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.