I'm migrating an old service to Asp.net, and need to preserve the legacy request format. The challenge is that the number of POST body parameters is variable, with the number specified by a count parameter. For example...
COUNT=3&PARAM1=A&PARAM2=B&PARAM3=C
I'm using ApiController for another call and it's working great. In this case though, I don't know how to define the model without creating a bunch of placeholder properties (PARAM1, PARAM2, ..., PARAM100).
So.. if I have this..
public class MyController : ApiController
{
public HttpResponseMessage MyService(MyServiceRequest request)
{
}
}
How can I define the MyServiceRequest class such that I can access PARAM1, PARAM2, etc (without just predefining more PARAM properties than i think i'd ever need)?
public class MyServiceRequest
{
public string COUNT { get; set; }
/* Don't want to have to do this
public string PARAM1 { get; set; }
public string PARAM2 { get; set; }
:
public string PARAM1000 { get; set; }
*/
}
Thanks!
Consider implementing custom model binder
//using System.Web.Http.ModelBinding;
public class LegacyBinder : IModelBinder
{
public bool BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext)
{
//reading request data
NameValueCollection formData = actionContext.ControllerContext.Request.Content.ReadAsFormDataAsync().GetAwaiter().GetResult();
var model = new MyServiceRequest
{
Params = new List<string>()
};
model.Count = formData["count"];
foreach (string name in formData)
{
//simple check, "param1" "paramRandomsring" will pass
//if (name.StartsWith("param", StringComparison.InvariantCultureIgnoreCase))
//more complex check ensures "param{number}" template
if (Regex.IsMatch(name, @"^param\d+$", RegexOptions.IgnoreCase))
{
model.Params.Add(formData[name]);
}
}
bindingContext.Model = model;
return true;
}
}
And tell framework to use this model binder for conrete model
[ModelBinder(typeof(LegacyBinder))]
public class MyServiceRequest
{
public string Count { get; set; }
public List<string> Params { get; set; }
}
Read more about model binding in ASP.NET Web API in the docs.