Reputation: 1176
I'm struggling with this for some time now. I've searched all over the internet, didn't find any solution.
I'd like to create a webapi project with somewhat custom routing. Using VS 2019, project is of type ASP.NET WebApi on .NET Core 2.2. Routing should be like this:
Basic application must reside on url similar to "https://my.server.com/myapi". URLs which will be called are in form "https://my.server.com/myapi/{InstanceName}/{CommandName}?{customParams}"
I have one controller defined in my project and I would like to redirect all requests to that controller, where instanceName could be parameter of all the methods contained in a controller, so I would get a value for that parameter. CommandName is basicly the same as "action" RouteData by MVC principles. As you can see there is no controller specified, since all is handled by one controller.
So far I've tried setup routing like this:
Startup.cs
app.UseMvc(routes =>
{
routes.MapRoute(
name: "MyRoute",
template: "{instance}/{action}",
defaults: new { controller = "MyController" });
});
}
MyController.cs
[Route("/")]
[ApiController]
public class MyController : ControllerBase
{
[HttpGet("{instance}/info")]
public JsonResult Info(string instance, InfoCommand model)
{
// Just return serialized model for now.
var result = new JsonResult(model);
return result;
}
}
But this does not work. I get 415 response from (I think) web server when I call for example
https://my.server.com/myapi/MYINSTANCE/info?param1=value1¶m2=value2
While debugging from VS this URL looks like this:
https://localhost:12345/MYINSTANCE/info?param1=value1¶m2=value2
but I think it shouldn't matter for routing.
In best case scenario (putting [Route("{instance}")]
above controller and [HttpGet("info")]
above Info method) I get 404
response, which is also what I do not want.
I've even tried creating my own ControllerFactory, but that didn't work either (changing controller inside ControllerFactory's create method and adding another parameter to RouteData).
How to setup routing like that? Is it even possible? I would still like to use all other MVC features (model binding, proper routing, auth features, etc.), it's just this routing I cannot figure it out.
Upvotes: 0
Views: 91
Reputation: 23314
Your attempt resulting a in 415 Unsupported Media Type error
was your best one.
You were only missing the FromQuery
as shown below.
The error indicates that the complex type InfoCommand
could not be resolved.
You must specify that it must be parsed from the querystring.
Note that the route defined via MapRoute
doesn't have effect, since you are using attribute-based routing; it's only one or the other.
[Route("/")]
[ApiController]
public class MyController : ControllerBase
{
[HttpGet("{instance}/info")]
public JsonResult Info(string instance, [FromQuery] InfoCommand model)
{
var result = new JsonResult(model);
return result;
}
}
public class InfoCommand
{
public InfoCommand()
{}
public string Param1 { get; set; }
public string Param2 { get; set; }
}
Upvotes: 2