C
C#2y ago
cumslvt13

✅ Binding array with default value doesn't work

I've got the following model and controller
public class MyModel
{
public int? Test { get; set; } = 10;
public IEnumerable<string> Sections { get; set; } = Array.Empty<string>();
}

[ApiController]
[Route("[controller]")]
public class TestController : ControllerBase
{
[HttpGet]
public ActionResult<MyModel> Test([FromQuery] MyModel model)
{
return Ok(model);
}
}
public class MyModel
{
public int? Test { get; set; } = 10;
public IEnumerable<string> Sections { get; set; } = Array.Empty<string>();
}

[ApiController]
[Route("[controller]")]
public class TestController : ControllerBase
{
[HttpGet]
public ActionResult<MyModel> Test([FromQuery] MyModel model)
{
return Ok(model);
}
}
The https://localhost:5001/test?Test=3&Sections=USER resolves to {"test":3,"sections":[]}, but if I remove default value for a Sections property it resolves to {"test":3,"sections":["USER"]}. Why behavior is different from int default value?
28 Replies
cap5lut
cap5lut2y ago
just guessing here: seems the way how its instance created will be filled with the correct data, but afterwars the property initializer is run, resulting in an overrriden value. can u test the behavior with required for Sections instead of giving a default value?
cumslvt13
cumslvt13OP2y ago
"property initializer is run, resulting in an overrriden value." - but this doesn't apply to nullable int which is also a reference type
cap5lut
cap5lut2y ago
indeed, its weird 😒
cumslvt13
cumslvt13OP2y ago
just tested same with string instead of int and it works, but arrays or rather collections seems to behave oddly
cap5lut
cap5lut2y ago
hmm, tbh im clueless now as well 🤔 if u expand the auto property to set a break point on the setter, u should be able to see whats going on, and maybe the stack trace info helps figuring out a solution, maybe? 😂
cumslvt13
cumslvt13OP2y ago
funny.
cumslvt13
cumslvt13OP2y ago
GET https://localhost:5001/test?Sections=TEST
cumslvt13
cumslvt13OP2y ago
and same but without a default value for backing property
cap5lut
cap5lut2y ago
the f... o.O i doubt its a bug in the model binding stuff.. but thats the only rason i can think of D: can u show the stacktrace of both variants?
cumslvt13
cumslvt13OP2y ago
stacktrace won't help actually tbh project is clean literally only Add and Map controllers
cap5lut
cap5lut2y ago
well, i dont want to see the parts of ur code, but where the model is created and how its filled by the framework ;p worst case i would file an issue in the repo, maybe it really is a bug but i would assume that response time there is quite long which dotnet version btw? (and asp.net version)
cumslvt13
cumslvt13OP2y ago
.net 7 same on behavior on 6
cap5lut
cap5lut2y ago
i gonna smoke and think, but im most likely out of ideas 😒 only ugly workarounds come to mind =/
ineternet
ineternet2y ago
Probably because it can't figure out how to put a single string in an array, but when it tries to make its own list, it makes a List<string> (and puts the value in) Either way why are you trying to fill a list/array from the parameters, if you can only put one value for the parameter in the URL?
cumslvt13
cumslvt13OP2y ago
There can be a several params: /test?Sections=TEST&Sections=TEST2
ineternet
ineternet2y ago
Web API parameter binding is not able to convert several parameters from the query string into an array
https://stackoverflow.com/questions/30318428/multiple-parameters-by-the-same-name
Stack Overflow
Multiple parameters by the same name
Consider the following ApiController: public class SomeController : ApiController { [HttpGet] public class SomeFunction(int someVal = 0) { ... } } This works as expected: htt...
cumslvt13
cumslvt13OP2y ago
new List intead of array seems to be working
ineternet
ineternet2y ago
i mean, array size cant be changed array.empty is length 0, it tries to put in the string, fails, so empty array
cumslvt13
cumslvt13OP2y ago
Yeah but, couldn't it just create a new array? I just was trying to be efficient and used empty array everywhere Guess I'll have to make a change then
ineternet
ineternet2y ago
It probably calls icollection.add or something like that, I doubt it implements proper inserting for each type of colleciton you could try Enumerable.Empty
cumslvt13
cumslvt13OP2y ago
Exception
cumslvt13
cumslvt13OP2y ago
cumslvt13
cumslvt13OP2y ago
Well, premature optimization is the root of evil I tried to be efficient and got backstabbed weird that asp doesn't throw in case of array like it does with enumerable empty
cap5lut
cap5lut2y ago
for what code u got that exception?
cumslvt13
cumslvt13OP2y ago
Changed Array.Empty to Enumerable.Empty
cap5lut
cap5lut2y ago
aah also i dont think thats premature optimization, its simply a well defined model imo i guess the question is answered now, right? so please $close it if thats the case
MODiX
MODiX2y ago
Use the /close command to mark a forum thread as answered
cumslvt13
cumslvt13OP2y ago
Guess yes...

Did you find this page helpful?