MVC Web Api as a middle tier service - c#

In our recent application we are planning to use MVC Web API as a Middler tier service. Meaning, front end will access the WebAPI middler tier service to get all the data it required from DB and to update the data back to DB. Along with this there may be many other methods that we will need. For example check whether user already exists in the system, Validate the address, etc. Now I have come into a point that my webapiconfig.cs routing is becoming more complex. For example my UserController in WebApi project will have following methods.
public User Get(int userId)
{
}
public bool IsUserExists(string username)
{
}
public bool UpdateUser([FromBody]User user)
{
}
public bool ChangePassword(string username, string password)
{
}
To manage all of these I may need so many routing configurations in webapiconfig.cs. I am not sure how to deal with these when other controllers comes to the picture. Should I use AttributeRouting? Any suggestion highly appreciated. Thanks.

If you have the option to use web api 2 go for attribute routing. You can save your lot of development effort in configuring routes.
Also make sure you are following resource based routing design and REST principles, than old RPC style routes. i.e for basic CRUD operations :-
Create - HTTP POST to /user
Read - HTTP GET to /user or /user/{id}
Update - HTTP PUT to /user
Delete - HTTP DELETE to /user/{id}
For example for updating an user
Instead of route /user/UpdateUser
You should do a
HTTPPUT to /user/
For more tips on REST check this.

Related

Health check, ASP.NET Web API

In my work I was asked to implement health checks into an ASP.NET Web API 2 written in C#. I have searched but all the documentation is for ASP.NET Core and its implementation, does anyone know how to implement health check featurs in the classic / full .NET Framework?
I agree with Igor. Here's a concrete application of what he suggested (obviously, there are other ways to do this, but this is the best way I know how to keep it clear and honor separation of concerns):
Create a new controller. In this example, I'll call it HealthController
Add an action to the controller, and annotate it with [HttpGet]
Place logic inside the action that checks for the stability of external dependencies. For example, if disk access is critical for your API, run a test or two to make sure that the disk is responding like you need it to. If you need to be able to query a database, make a sample query, and make sure it's successful. This part is completely custom and really depends on your API and how it needs to perform.
public class HealthController : ApiController
{
[HttpGet]
public IHttpActionResult Check()
{
// Add logic here to check dependencies
if (/* successful */)
{
return Ok();
}
return InternalServerError(); // Or whatever other HTTP status code is appropriate
}
}
Have an external service issue a GET request to your endpoint (currently at https://whatever.your.domain.is/Health/Check) and report back when it doesn't receive 200 OK for some amount of time.
I've used Amazon CloudWatch in the past and I've been happy with it. There are going to be other services out there that will do this for you, but I don't have any experience with them.

How to create an attribute that serve as a Web API?

I am working on a project that we need to shift the responsibility of authorization level to the separated Web API.
What is important creating an attribute class in Web API which able to check some policies. What we want is adding the Web API reference to other projects and check these policies by adding AuthPolicyAttribute above actions and controllers. By adding this attribute, Web API check accessibility by getting the action name and user name.
For example (This is one of the actions in a project that need to call Web API by AuthPolicy attribute):
[AuthPolicy]
public IActionResult GetTypes([FromBody]Input input)
{
// Code
}
I've searched a lot but unfortunately, I haven't found any example.

Exposing a few calls from an existing asp.net-mvc site to other REST clients within an intranet?

I have an existing asp.net-mvc web site and now I need to expose of a few of my calls to external applications that are only used within my site right now. This is all happening within an intranet within my company.
I have read this page which explains Web API versus controller actions as well as this SOF question which seems to have a similar issue but the answers seem a bit outdated. So I am trying to determine given the latest available functionality what is the simplest solution to meet my requirement.
In my case, since I already have the same controller actions used within my current website then WEB API doesn't really make sense but if I google anything around asp.net-mvc authentication or security I only see articles around web API.
Given that, I am trying to figure out best practice for exposing my controller action to another application.
In an ideal world you would convert the app to web api controllers as someone else suggested but to be more pragmatic you can implement an interim solution where you expose only the required calls via extending ApiController
You did not mention which version of MVC your current app is using nor did you mention how your current Controllers return data to the web app.
I will therefore assume you return data via a view model and razor views. eg:
public class ProductsController : Controller
{
public void Index()
{
var view = new ProductsListView();
view.Products = _repository.GetProducts();
return View(view);
}
}
Suppose now you want to expose the products list via a REST-like api?
First check you have web api installed (via nuget)
Install-Package Microsoft.AspNet.WebApi
(again i'm not sure what ver of asp.net you are on so this process may differ between versions)
Now in your public void Application_Start()
GlobalConfiguration.Configure(WebApiConfig.Register);//add this before! line below
RouteConfig.RegisterRoutes(RouteTable.Routes);//this line shld already exist
and in WebApiConfig
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
I like to create a dedicated folder called ApiControllers and add controllers with the same name; this way you can have controllers with the same names as they are in different namespaces:
namespace YourApp.Web.ApiControllers
{
[AllowAnonymous]
public class ProductsController : ApiController
{
[HttpGet]
public HttpResponseMessage Products()
{
var result = new ProductResult();//you could also use the view class ProductsListView
result.Products = _repository.GetProducts();
return Request.CreateResponse(httpStatusCode, result);
}
}
}
You can then access this via yourapp.com/api/products
nb, try to reduce duplication of code inside controllers - this can be acheived by extracting common parts into service classes.
While I would highly recommend using a web service architecture, such as Web API or ServiceStack, you can expose controller actions.
You'll first want to decorate the actions with the [AllowAnonymous] attribute. Then, in your web.config you'll need to add the following code block to the configuration section for each action you want exposed.
<location path="ControllerNameHere/ActionNameHere">
<system.web>
<authorization>
<allow users="*" />
</authorization>
</system.web>
</location>
As you may have guessed, this becomes very repetitive and annoying, which is why web services would be a great choice.
I had a similar requirement where website 2 needed to call some controller actions from website 1. Since there was no changes in the logic I wanted to avoid the whole rewrite using web API. I created another set of controller and actions that would return Json. The new controller actions would call the original controller actions and then convert the result data to json before returning. The other applications (website 2) would then make http get and post requests to get json data and deserialize it internally. Worked nicely in my case.
I didn't have to put a security layer over the json based actions as they were public, but you might need one to authenticate the requests.
Although webapi is the best way but you don't need to convert your controller/actions to webapi at all.
You could easily achieve what you are after by restricting the controller/actions by IP addresses from your intranet. Just make sure that all intranet sites reside on the same domain other cross domain jquery ajax calls will not work.
Here is an eg. Restrict access to a specific controller by IP address in ASP.NET MVC Beta
An alternative is to use basic authentication and only allow a hardcoded userid/password to access those controller/actions and call via ajax:
beforeSend: function (xhr) {
xhr.setRequestHeader ("Authorization", "Basic " + btoa(username + ":" + password));
},

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