I'm trying to implement a REST API in ASP.Net MVC. This is my code:
[Route("api")]
[ApiController]
public class ContactsController : ControllerBase
{
[HttpGet]
[Produces("application/xml")]
[Route("api/areas/{areaName}/contacts/{contactID}")]
public ActionResult<XmlDocument> Get(string areaName, string contactID)
{
return new XmlDocument();
}
}
However, when I surf to /api/areas/foo/contacts/bar, I encounter HTTP 404.
How can I fix my code?
Note that ActionResult<T> is part of asp.net-core and not the previous asp.net-mvc version. This means that you originally tagged the question incorrectly.
That said, the URL being called does not match the route template of the intended action and thus you will get a not found when trying to call the action.
Reference Routing to controller actions in ASP.NET Core
The provided route has [Route("api")] on the controller and [Route("api/areas/{areaName}/contacts/{contactID}")] on the action, which when combined would result in a URL that looks like
api/api/areas/foo/contacts/bar
I believe the intention was to have api only once so I would suggest remove one of them
Either from the action
[Route("api")]
[ApiController]
public class ContactsController : ControllerBase {
[HttpGet]
[Produces("application/xml")]
//GET api/areas/foo/contacts/bar
[Route("areas/{areaName}/contacts/{contactID}")]
public ActionResult<XmlDocument> Get(string areaName, string contactID) {
return new XmlDocument();
}
}
or removing the prefix on the controller
[ApiController]
public class ContactsController : ControllerBase {
[HttpGet]
[Produces("application/xml")]
//GET api/areas/foo/contacts/bar
[Route("api/areas/{areaName}/contacts/{contactID}")]
public ActionResult<XmlDocument> Get(string areaName, string contactID) {
return new XmlDocument();
}
}
Related
I'm new to ASP Net and I'm having a little trouble passing a URL as a simple parameter.
These are the solutions that I've tried:
[ApiController]
[Route("api/[controller]")]
public class LoginRedditController : ControllerBase
{
[HttpGet("{*longUrl}")]
public ActionResult<string> Get(string longUrl)
{
Console.WriteLine(longUrl);
return "OK";
}
}
This is the URL that I've tried to call:
http://localhost:5001/LoginReddit?longUrl=https://www.reddit.com/r/playmygame/comments/glftsj/stickn_roll_collect_everything_as_you_roll/
I also tried to encode the URL but the result is the same: I got a "ERR_EMPTY_RESPONSE"
This is my second try:
[ApiController]
[Route("api/[controller]")]
public class LoginRedditController : ControllerBase
{
[HttpGet]
public ActionResult<string> Get([FromQuery]string url)
{
Console.WriteLine(longUrl);
return "OK";
}
}
I used the same URL used before but I got the same result.
In my tried try I changed the Route like this:
[Route("api/[controller]/{url}")]
public class LoginRedditController : ControllerBase
{
[HttpGet]
public ActionResult<string> Get([FromQuery]string url)
{
Console.WriteLine(longUrl);
return "OK";
}
}
And I've tried with the following URL:
http://localhost:5001/LoginReddit/https://www.reddit.com/r/playmygame/comments/glftsj/stickn_roll_collect_everything_as_you_roll/
Also encoded but I got the same resoult.
Where is the problem guys?
For a URL like this:
http://localhost:5001/LoginReddit?longUrl=https://www.reddit.com/…
You would write your controller action like this:
[ApiController]
[Route("[controller]")]
public class LoginRedditController : ControllerBase
{
[HttpGet]
public ActionResult<string> Get(string longUrl)
{
Console.WriteLine(longUrl);
return "OK";
}
}
The longUrl string value is automatically taken from the query arguments passed to the route. And the route for the action is combined from that [Route] attribute on the controller and the [HttpGet] attribute on the action.
The Route Attribute specified the format of the url. You missed the "api" part in your url, and it should be like this:
http://localhost:5001/api/LoginReddit?longUrl=https://www.reddit.com/r/playmygame/comments/glftsj/stickn_roll_collect_everything_as_you_roll/
[ApiController]
[Route("api/[controller]")]
public class LoginRedditController : ControllerBase
{
[HttpGet]
public ActionResult<string> Get([FromQuery]string url)
{
Console.WriteLine(longUrl);
return "OK";
}
}
I'm brand new to C# and ASP.Net
I am trying to model some endpoints:
/api/sites/
/api/sites/{id}/
/api/sites/{id}/readers/
/api/sites/{id}/readers/{id}/
I already have a SitesController
[Route("api/[controller]")]
[ApiController]
public class SitesController : ControllerBase {
[HttpGet("{id:length(24)}")]
public ActionResult<Site> Get(string id) {}
}
I've tried adding a ReadersController inside the SitesController class
[Route("{id:length(24)}/[controller]}")]
[ApiController]
public class ReadersController {
[HttpGet]
public string Get() => "test";
}
I can't hit the endpoint /api/sites/{id}/readers/ though so I'm not sure I'm doing this right. Is there some way I can do this while still using the [Route] tags?
You shouldn't be nesting controller classes. Make a new class for ReadersController then setup the routes like this:
[Route("api/[controller]")]
[ApiController]
public class SitesController : ControllerBase {
[HttpGet("{siteId:length(24)}")]
public ActionResult<Site> Get(string siteId) {}
}
[Route("api/sites/{siteId:length(24)}/[controller]")]
[ApiController]
public class ReadersController {
[HttpGet]
public string Get() => "test";
[HttpGet("{readerId:length(24)}")]
public ActionResult<Site> Get(string siteId, string readerId) {}
}
You can use routes.MapRoute to create more complex rules however if you want to keep it easy and specify routes for each individual endpoint then you can carry on using HttpGet or Route attributes. Or if you want to make it explicit you can write out the whole route in each HttpGet and ignore the Route attribute on the controller.
If you are building apis with asp.net core, please check this.
Link
You can use routes.MapRoute functions as many as you can.
Like this.
routes.MapRoute(
name: "default_route",
template: "{controller}/{action}/{id?}");
routes.MapRoute(
name: "default_route",
template: "{controller}/{action}/{id}/readers/{id?}");
Can anybody help me with this link?
[Route("api/[controller]")]
public class AuthController : ControllerBase
{
private readonly IAuthService _auth;
public AuthController(IAuthService auth)
{
_auth = auth;
}
[HttpGet("getuser/{sessionGuid}")]
public IActionResult Get(Guid sessionGuid)
{
\\code
}
How should the URL be written in order to get to public IActionResult Get(Guid sessionGuid)?
The Route("api/[controller]") attribute you have given your Controller tells the framework to use the name of the Controller as part of the route.
In this case you have an AuthController so all the routes in this Controller will be prefixed with api/auth/.
Additionally you've specified to the framework to map you Get method to the "getuser/{sessionGuid}" route (where sessionGuid is some Guid).
Putting this together the URL you need to call is api/auth/getuser/{sessionGuid}.
All of this needs to be prefixed by the hostname etc. http://localhost:5000/ for example.
Move your route onto the function, and configure it however you'd like.
In my example, it would be: HTTP GET : http://api.com/my/ur/with/as/many/slashses/as/I/want/52
public class AuthController : ControllerBase
{
private readonly IAuthService _auth;
public AuthController(IAuthService auth)
{
_auth = auth;
}
[Route("my/url/with/as/many/slashes/as/I/want/{sessionGuid}")]
[HttpGet("{sessionGuid}")]
public IActionResult Get(Guid sessionGuid)
{
\\code
}
}
Is it possible to achieve url parameter and attribute based versioning with same Controller methods. To explain that, suppose I have one controller like,
[RoutePrefix("api/{apiVersion:apiVersionConstraint(v2)}/values")]
public class ValuesController : ApiController
{
// GET api/v2/values
[Route("")]
public IEnumerable<string> Get()
{
return new string[] { "v2-value1", "v2-value2" };
}
// GET api/v2/values/5
[Route("{id}")]
public string Get(int id)
{
return "v2-value-" + id;
}
}
Now, I want to access the API endpoint by both of the following URL's:
http://hostname/context/api/v1/values
http://hostname/context/api/values?v=1
Is it possible?
N.B. I'm using the example at WebApiNamespaceVersion in GitHub
I am doing a Web API 2 application and I have controller named NCT_ProcessSettings and already I have two GET methods as below.
1. public IEnumerable<Process_Settings> Get()
2. public HttpResponseMessage Get(int id)
Now I want to have third one as below (Same as first one but inside I will write different logic).
3. public IEnumerable<Process_Settings> Get() //Compiler will confuse which to pick?
I tried as below.
[HttpGet]
[Route("GetGlobalSettings")]
public IEnumerable<NCT_Process_Settings> GetGlobalSettings()
{
return entityObject.NCT_Process_Settings.Where(c => c.project_id == 0).ToList();
}
Below is my angularcode to call api.
var url = '/api/NCT_ProcessSettings/GetGlobalSettings';
May I have some idea how to fix this? Any help would be appreciated?
Enable attribute routing in WebApiConfig.cs before convention-based routes.
config.MapHttpAttributeRoutes();
Next update controller to use routing attributes. (note the route prefix)
[RoutePrefix("api/NCT_ProcessSettings")]
public class NCT_ProcessSettingsController : ApiController {
//GET api/NCT_ProcessSettings
[HttpGet]
[Route("")]
public IEnumerable<Process_Settings> Get() { ... }
//GET api/NCT_ProcessSettings/5
[HttpGet]
[Route("{id:int}")]
public HttpResponseMessage Get(int id) { ... }
//GET api/NCT_ProcessSettings/GetGlobalSettings
[HttpGet]
[Route("GetGlobalSettings")]
public IEnumerable<NCT_Process_Settings> GetGlobalSettings() { ... }
}
Read up more documentation here Attribute Routing in ASP.NET Web API 2
Used Action Name attribute
[ActionName("Get")]
public IEnumerable<Process_Settings> Get1()//used any name here
{
}