I'm trying to follow the article Build RESTful API's with ASP.NET Web API to learn how to create a RESTful API.
I created the first project and controller, Contact.
public class ContactController : Controller
{
// GET: Contact
public string[] Index()
{
return new string[]
{
"Hello",
"World"
};
}
}
But when I load the URL in a browser, instead of getting the response described in the article (["Hello","World"]). The response I get is System.String[].
I don't understand what I'm missing.
BTW, the article is from 2013. Does anyone know of a good article that is perhaps a little newer?
What you have now is simple ASP.NET MVC controller. For Web API controller you should inherit your controller from ApiController instead of Controller:
public class ContactController : ApiController
Also action names should start with HTTP verb. If you'll send GET request to /api/contact endpoint you'll get error
The requested resource does not support http method 'GET'.
By default action name is not used in route for Web API controllers. If you'll check default route configuration, it will be api/{controller}/id. Correct action is selected via HTTP method of request. In your case it should be GetXXX or simply Get
You cannot Return regular primitives from the Web Apis. At least if not if you are using a regular MVC Web API from .net. So, if this is the case you could do something like
public class ContactController : Controller
{
// GET: Contact
public JsonResult Index()
{
return Json(new { value1: "Hello", value2: "world" }, JsonRequestBehavior.AllowGet);
}
}
Hope this helps
Related
I would like to list all the available endpoints a controller provides.
Is it possible to access the component(s) .NET uses to generate these routes (by, for instance providing it a type or controller name (string))?
The methods/verbs (so, POST, GET) are not even that important for my scenario, just the routes themselves.
Example
Please, take a look on the below ASP.NET Core code.
[ApiController]
[Route("[controller]")
public class HomeController : ControllerBase
{
[HttpGet("additional")]
public async Task<IActionResult> Whatever()
{
// ...
}
}
So, the method will be exposed as a GET endpoint on the URL of Home/additional.
I am creating a c# .net core 2.2 web API for my next project. My question is when returning data should I return the object or IActionResult OK(returnObject)?
The reason I ask is I am using swagger and swagger studio to create my models for an Angular front end. If I return an IActionResult from the API the returned view models are not detailed in the swagger.json file so I would have to code these in the angular application. If I return whatever object is created the model is created in the swagger.json.
What practice should I follow to return data from an API in this case?
You do want to return IActionResult(object) but you are not quite done.
Annotate your controller with the ProducesAttribute and annotate your method with the ProducesResponseTypeAttribute:
[Produces("application/json")]
public class SomethingController
{
[ProducesResponseType(typeof(YourObject), (int)HttpStatusCode.OK)]
public IActionResult GetThing(int id)
{ ... }
}
This allows Swagger UI to know what to expect and document it appropriately. Shown above is for a synchronous method; it works for asynchronous as well.
You can return
- Specific Type
- IActionResult
- ActionResult
For more details, please refer MSDN article at : https://learn.microsoft.com/en-us/aspnet/core/web-api/action-return-types?view=aspnetcore-2.2
I am making an ASP.net core 2.0 Web API and have a method in my controller called
[HttpPost("Create")]
public void Create()
{
// var d = employee;
}
Does the HttpPost act as the same the [Route] attribute or do I need both?
For Asp.Net Core Web API you do not need both.
It acts the same as Route and is the advised approach. When using MVC with views you use Route and Http{Verb} together.
Documentation states...
When building a REST API, it's rare that you will want to use [Route(...)] on an action method. It's better to use the more specific Http*Verb*Attributes to be precise about what your API supports. Clients of REST APIs are expected to know what paths and HTTP verbs map to specific logical operations.
Reference Routing to Controller Actions in ASP.NET Core
I would also advise having your actions return IActionResult to allow the proper HTTP Verb to be returned from the action.
[HttpPost("Create")]
public IActionResult Create() {
// var d = employee;
return Ok();
}
void actions always return 200 OK unless an exception is thrown. This limits the possible response from the action.
I use a custom middleware to change the Path used in a request to a WebApi.
In my middleware Invoke, I have:
// code prior to this extracts controller name and remaining path
var newPath = $"/{version}/{controller}/ToDoItemDto/{remainingPath}"; // ToDoItemDto was inserted by me and was not in the original request
context.Request.Path = newPath;
return _next(context);
In my ToDoController, I have:
[Route("api/v{version:apiVersion}/[controller]")]
// other attributes for the controller
public class TodoController : Controller
{
// ...
[HttpGet("TodoItemDto/{primaryId}", Name="GetTodoById")]
public IActionResult GetById(long primaryId)
{
// code here...
}
}
However, when I attempt to access this controller, I get an Http 405 error with the following result:
{"error":{"code":"UnsupportedApiVersion","message":"The HTTP resource that matches the request URI 'http://localhost:1482/v1/todo/ToDoItemDto/1' does not support the API version '1'.","innerError":null}}
I tried adding the following attribute to my GetById() method:
[MapToApiVersion("1.0")]
but that did not help.
I searched the web and found a promising result on the GitHub page for the versioning Api. However, I don't understand the suggested fix (using an IActionResult) in this context.
Can custom route matching be done while also using versioning? If so, how?
You have missed to add api in the route. Try it this way
var newPath = $"api/{version}/{controller}/ToDoItemDto/{remainingPath}";
I have a web api controller and two GET methods:
public class ImagesController : ApiController {
[HttpGet]
public HttpResponseMessage GetImages() { }
[HttpGet]
public HttpResponseMessage Download([FromUri]int[] ids) { }
}
Why I'm getting multiple actions found error, when trying to reach /api/Images, why both actions are the same?
When you created controller, you have assigned HttpGet to two different methods. Making that you have confused web server when it tries to process your request. Since you are sending GET verb to the controller it self, instead directly to the method, web server can not determinate what method should be invoked.
You can try with /api/Images/GetImages in order to directly hit a method, or remove one of listed.
If you see the Web API feature it work for the selected httm methods like GET,PUT,POST,DELETE.
So if you create two action method with same name it will give error. To avoid this error you have to redefine the DefaultAPI path in route.config file.
Change it to
API/{controller}.....
After changing this acces your API from browser like
Or
Mark as a answer if this resolve your issue.