Is ApiController deprecated in .NET Core - c#

Is it true that "ApiController will get deprecated in .NET Core"? Asking since I'm planning to use it in new projects.

Update ASP.NET Core 2.1
Since ASP.NET Core 2.1 a new set of types is available to create Web API controllers. You can annotate your controllers with the [ApiController] attribute which enables a few new features such as automatic model state validation and binding source parameter inference. See the docs for more information:
https://learn.microsoft.com/en-us/aspnet/core/web-api/index?view=aspnetcore-2.1#annotate-class-with-apicontrollerattribute.
There is indeed no particular ApiController class anymore since MVC and WebAPI have been merged in ASP.NET Core. However, the Controller class of MVC brings in a bunch of features you probably won't need when developing just a Web API, such as a views and model binding.
You've got two options if you want something different:
Use the ControllerBase class in the Microsoft.AspNetCore.Mvc.Core package.
Or
Create your ApiController base class. The key here is to add the [ActionContext] attribute which injects the current ActionContext instance into the property:
[Controller]
public abstract class ApiController
{
[ActionContext]
public ActionContext ActionContext { get; set; }
}
Also, add the [Controller] attribute to the class to mark it as a controller for the MVC controller discovery.
See more details in my “Web API in MVC 6” blogpost.

The [ApiController] attribute actually got added back in ASP.NET Core version 2.1.
Features coupled with the attribute are:
Validation errors automatically trigger an HTTP 400 response.
No more need to define [FromBody], [FromRoute], ... attributes explicitly
Links to the docs:
https://learn.microsoft.com/en-us/aspnet/core/aspnetcore-2.1?view=aspnetcore-2.1#apicontroller-actionresult
https://learn.microsoft.com/en-us/aspnet/core/web-api/index?view=aspnetcore-2.1#annotate-class-with-apicontrollerattribute
Update
There is also the baseclass ControllerBase for controllers to inherit from which is suited for api-controllers because it ommits all view-related functionality.
https://learn.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.mvc.controllerbase?view=aspnetcore-2.1

In ASP.NET core uses terms and concepts known from ASP.NET MVC and ASP.NET WepAPI. But basically it is a complete new framework. Therefore there are several concepts or base classes that we can simply forget.
ASP.NET MVC and ASP.NET WebApi are two coexisting but different frameworks and therefore a destinction has to be made to specify a controller as a WebApi Controller by using the ApiController as base class.
In ASP.NET Core this is simply not necessary anymore. The Controller base class can be used for actions that return HTML from Razor Views or JSON (with output formatters XML and other formats are possible as well). You don't even need the Controller base class. It is even possible to use a "Plain Old C# Object" as Controller without inheritence.
Below is an example of a Demo-Controller to outline, that even though the ApiController is not there, the structural approach to deliver data to the client is similar.
public class DemoController : Controller
{
public async Task<IActionResult> Action()
{
var model = await _someService.GetPreciousData();
return Ok(model);
}
}

As others mentioned, ASP.NET Core is a complete new webstack that's not compatible with the old ASP.NET MVC webstack. This is explicitly reflected in it's name and versioning!
ASP.NET Core and ASP.NET Core MVC have the version 1.0.0 to make this incompatibility very clear.
ASP.NET Core merged the MVC and WebApi into one single Api just called.
And here's the thing you may have been looking for:
If you are migrating from a previous ASP.NET MVC or ASP.NET WebApi application, you may want to import the Microsoft.AspNetCore.Mvc.WebApiCompatShim package which provides some compatibility types which makes migrations easier from the previous versions. Among them is the ApiController class and certain attributes that were removed in the new webstack Api.
However, please note that this is only there to help you with migrating existing applications. When you create a new application you shouldn't use this compatibility shim and just use the new stuff.

Related

Custom AuthorizeAttribute with .NET Core 3.1

I am currently in the process of trying to migrate a .NET Framework 4.7 ASP MVC application over to .NET Core 3.1. I am using ASP.NET Core and found when I did the conversion I had issues with some of the custom authorization filters I was using on my methods. I want to retain the current attributes if possible, but I NEED access to the actual instance of the controller object - so I can set the value of an object inside that controller I can then access (for example, a User ID or other object) but I am unable to get the instance.
I want to decorate specific Actions with this attribute and when an incoming request comes through, perform some validation logic.
I've seen other code examples showing how via reflection I can get the controller name or type, but I need the ACTUAL INSTANCE not just the details of the object. Hope this is clear, any help is appreciated.
public class CustomAuthorizeAttribute : AuthorizeAttribute, IAsyncAuthorizationFilter
{
public async Task OnAuthorizationAsync(AuthorizationFilterContext authorizationFilterContext)
{
//How can I access the Controller instance here
//Not just the controller name, I need the actual instance
}
}

Use another controller from different project on asp.net core

We trying to rewrite out old project to form old mvc to the asp.net core mvc. we used to attach another mvc project as reference and called the controller without problem. but on the new asp.net core MVC it seems it need another work around
so the webapplication9 added webapplication1 as reference. and call the canary but it return 404. it worked on old mvc.
the controller just return the plain content
namespace WebApplication1.Controllers
{
public class CanaryController : Controller
{
public IActionResult Index()
{
return Content("Canary");
}
}
}
is there some part need to add to make webapplication9 able to call the webapplication1 controller?
on old MVC 5 we can just called it on URL http://webapplication9/Canary and it works.
on asp.net core it return 404 or not found
First, your other projects shouldn't be an Web application, but a normal PCL.
Second, after you reference it, you need to tell ASP.NET Core that it should look for controllers there. For that reason the Application Parts Api exists.
services.AddMvc()
.AddApplicationPart(typeof(CanaryController).GetTypeInfo().Assembly);
P.S. while the docs state it should work out of the box, when doing integration tests/unit tests on the controllers the .AddApplicationPart is still required, at least was the case in ASP.NET Core 2.0

Web Api and MVC Individual Account

in visual studio 2013 i've created a web api project (selecting also mvc framework in the wizard)
Anyway in the Controllers i've only the AccountController class derived from ApiController
public class AccountController : ApiController
It's possible, in the same project, have a mvc controller and api controller? How can i handle the authentication (signup, login,ecc...) with api controller and mvc controller?
The wizard generate only the apicontroller
you can certainly create a new MVC controller with the same name, as long as your route configurations dontcreate any clashes. The MVC controller will implement Controller rather than ApiController.
As you may expect, you will need to make sure you dont have any namespace clashes either.
For authentication there are separate AuthorizeAttributes you can use. The one in System.Web.Http is for WebAPI and the one for MVC can be found in System.Web.MVC

Demerit of using MVC Controllers for Web API's

In our application, which is Single Page application, we are using MVC controller(Action methods as API) for CRUD operation's. Which I feel its wrong.
Can someone tell me if its correct?
Eg:-
I have an API Controller say :-
public class MockAPIController : ApiController
{
// GET api/MockAPI/5
public ClassA GetSomething(int id)
{
return new ClassA();
}
}
and this can be called from client-side using /api/MockAPI/GetSomething/1. Similarly if I create MVC Controller like:-
public class MockAPIController : Controller
{
// GET api/MockAPI/5
public ActionResult GetSomething(int id)
{
return new JsonResult(new ClassA(),JsonRequestBehavior.AllowGet);
}
}
Still, I can get it work. Can some-one tell me whats demerit of using MVC controller for API?
EDIT:-
Is it recommended to use MVC Controller for API methods?? If Not, then can someone point out the -ve aspect of it?
Using the web API you can return objects as normal and your clients can specify the content-type.
This will automatically serialize the objects to xml or json without the need to specify a new action just to change the return type.
So your API call will always remain as:
public ClassA GetSomething(int id)
{
return new ClassA();
}
But it is capable of returning xml and json without any changes in the controller.
Web API provides cleaner way to craft your HTTP responses. It is extremely extensible, testable and faithful to the HTTP spec.
Web API was NEVER intended to provide an "out-of-the-box" REST framework.
MVC is a HTTP framework, optimized for serving content to a Web Browser. Web API has no bias as to what client is using it.
As per my understanding,
MVC controllers are extended over API Controller. You can do almost
everything what can be done with API Controller.
(People please correct me if I am wrong, its purely my understanding which I am sharing!)
Now, if your application is a web based application/internet or intranet where you have very few api call's then you can stick with MVC Controllers. Only care that need to be taken care is sending data as JsonResult(basically serializing`to JSON or whatever). If you have more funda of SPA, the API controllers is what you need.
I myself have not found much articles stating a strong line separating what to use when, it's always a developers pain to decide and implement.
It's less about merit and demerit of using ApiControllers in place of Controllers, and more about implementation and usage.
ApiControllers are specifically meant for building REST-ful Apis which return serialized data to the client in simplest form.
And, using controllers you can return Views, Different Types of ActionResults in different form. You can definitely convert the type of data you are returning, like the way you are using here but it's not the same with ApiControllers.

Is it possible for ASP.NET MVC website (not project) to return HttpResponseMessage

I am creating a RESTful webservice using ASP.NET MVC (not ASP.NET Web API). What I want to do is have every method in the controller return their result based on an input parameter (i.e. json or xml).
If I were using ASP.NET Web API, the HttpResponseMessage works for this purpose. When I attempt to return an HttpResponseMessage from a controller in ASP.NET MVC, there is no detail.
I have read that in this approach, I am supposed to use ActionResult. If I do this, then I need to create an XmlResult that inherits from ActionResult since it is not supported.
My question is why HttpResponseMessage does not work the same in both situations. I understand that in Web API, we inherit from ApiController and in ASP.NET MVC we inherit from System.Web.Mvc.Controller.
Any help is greatly appreciated.
Thanks,
EDIT 1
Much thanks to Fals for his input. My problem was in how to create an empty website and add all of the necessary functionality in. The solution was to use Nuget to get the packages mentioned in the comments and then to follow the steps in How to integrate asp.net mvc to Web Site Project.
Web Api is a Framework to develop Restfull services, based on HTTP. This framework was separeted into another assembly System.Web.Http, so you can host it everywhere, not only in IIS. Web API works directly with HTTP Request / Response, then every controller inherit from IHttpController.
Getting Started with ASP.NET Web API
MVC has It's implementation on System.Web.Mvc. coupled with the ASP.NET Framework, then you must use It inside an Web Application. Every MVC controller inherits from IController that makes an abstraction layer between you and the real HttpRequest.
You can still access the request using HttpContext.Response directly in your MVC controller, or as you said, inheriting a new ActionResult to do the job, for example:
public class NotFoundActionResult : ActionResult
{
private string _viewName;
public NotFoundActionResult()
{
}
public NotFoundActionResult(string viewName)
{
_viewName = viewName;
}
public override void ExecuteResult(ControllerContext context)
{
context.HttpContext.Response.StatusCode = 404;
context.HttpContext.Response.TrySkipIisCustomErrors = true;
new ViewResult { ViewName = string.IsNullOrEmpty(_viewName) ? "Error" : _viewName}.ExecuteResult(context);
}
}
This ActionResult has the meaning of respond thought HTTP Error.
As a matter of fact, it is indeed possible. You basically have two options:
develop your custom ActionResult types, which can be an heavy-lifting work and also quite hard to mantain.
add WebAPI support to your website.
I suggest you to do the latter, so you will have the best of two worlds. To do that, you should do the following:
Install the following Web API packages using NuGet: Microsoft.AspNet.WebApi.Core and Microsoft.AspNet.WebApi.WebHost.
Add one or more ApiControllers to your /Controllers/ folder.
Add a WebApiConfig.cs file to your /App_Config/ folder where you can define your Web API routing scheme and also register that class within Global.asax.cs (or Startup.cs) file.
The whole procedure is fully explained here: the various steps, together with their pros-cons and various alternatives you can take depending on your specific scenario, are documented in this post on my blog.

Categories

Resources