burnersk
burnersk

Reputation: 3500

How to implement a C# model class for properties that may occur multiple times (prop, prop2, prop3, ...)?

I have a ASP.NET Core 2.1 API web service.

The web service should be extended with an new API endpoint that can consume the following request (HTTP POST body is www-form-urlencoded):

foo=1&bar=2&baz=3&baz_2=3&baz_2=4

The above www-form-urlencoded in a more human readable way:

The parameters foo and bar exists exactly and only 1 time within the request. The parameter baz exists at least 1 time within the request. It is common that the baz parameter occurs multiple times, but I have seen occasions in which there where only a single baz parameter.

I have no impact on the sender. I have the option to either consume the request in the above described format, or cannot receive the data at all. And I need this data, which will be supplied only in the above described manner.

I have modeled a C# model class for the parameters that exists only 1 time within the request:

namespace StackOverflow.WebAPI.Models
{
    public class ConsumeRequest
    {
        public int foo { get; set; }
        public int bar { get; set; }

        public ConsumeRequest()
        {
            foo = 0;
            bar = 0;
        }

        public ConsumeRequest(int foo, int bar)
        {
            this.foo = foo;
            this.bar = bar;
        }
    }
}

The model shall be used as a Action parameter, such as:

namespace StackOverflow.WebAPI
{
    public class EndpointController : BaseController
    {
        [HttpPost]
        public JsonResult Consume([FromBody] ConsumeRequest data)
        {
            // Do something with data.
            return new JsonResult("ok");
        }
    }
}

Ideally, baz would be a List<int>. The order of the List would represent the "order" of the bazs (baz, baz_2, baz_3, ...).

How do I extend the model implementation to feature the baz parameter?

Upvotes: 0

Views: 100

Answers (1)

Chris Pratt
Chris Pratt

Reputation: 239430

That's not a valid request format to bind as you're looking to. The baz_2 key will literally translate to something like a Baz_2 property, not the second item in Baz collection. For that, the key must be something like baz[], repeated as many times as necessary. For example:

?baz[]=3&baz[]=4

Which will create a collection of the values [3, 4].

If the issue is that you don't have control over the format of the query string, that's a client issue, not an issue for you. An API is literally an interface. It enforces a particular form and function of the request, and not conforming to that interface is a bad request. You should not ever alter you API to accommodate a client; rather the client needs to alter their code to conform to your API.

That said, if you have no choice here, the only thing you can do is literally add a Baz_2 property and Baz_3, Baz_4, etc. up to as many as you need. However, there will always be some limit, due to these having to be literal properties that you must actually add to the class that you're binding to.

Upvotes: 1

Related Questions