Asp.Net MVC Consuming a web api from a Class Library - asp.net-mvc

I am wondering if there is a way to create a class library that contains web API, so I can use the dll as a plug-in, to inject into the MVC application.
Thank you in advance for your help.

Web API methods are called over HTTP, so calling a Web API service requires it to be hosted somewhere and called using a suitable client as detailed in #David's link. You can self-host Web API, so in theory you could have an assembly local to an MVC application which contained a class which set up and then called a self-hosted Web API service.
You would inject the Web API service behind an interface, something like this:
public interface IProductsService
{
IEnumerable<Product> GetAllProducts();
}
...implemented something like this:
public class SelfHostedWebApiProductsService
{
public SelfHostedWebApiProductsService()
{
// Set up a self-hosted Web API service
}
public IEnumerable<Product> GetAllProducts()
{
// Call your self-hosted WebApi to get the products
}
}
Configure your DI container to use SelfHostedWebApiProductsService for the IProductsService interface, and away you go. This article details how to set up and call a self-hosted Web API.
As the SelfHostedWebApiProductsService sets up the self-hosted Web API in its constructor - a relatively expensive operation - you might want to consider giving this class a singleton lifetime in your DI container.

You could Self-Host a Web API:
http://www.asp.net/web-api/overview/hosting-aspnet-web-api/self-host-a-web-api
You can put all your controllers in a Class Library project.
Then use Autofac to resolve the dependencies in your host project:
https://code.google.com/p/autofac/wiki/WebApiIntegration

Related

Integrate Open Policy Agent with ASP.Net Core web API

I was going through some videos and tutorials on OPA (Open Policy Agent) and found it really cool to use it for implementing Authentication and Authorization across multiple services / APIs. However I am not able to get any insights on how to install it on windows and integrate it with an ASP.Net core Web API to implement Authentication and Authorization. Can anyone help me in this ?
Thanks,
Amit Anand
Without knowing more about your use case or the platform you're running on, here's some general advice.
Architecture. Decide whether you want to run OPA as a sidecar or as a standalone service. That's an architectural question that will depend on latency, performance, and the data you need for your policies. OPA is a building-block designed as a sidecar, but you can build a service around OPA by spinning up multiple copies, load-balancing across them, adding a persistence layer, etc.
Administration. Decide how to load/update policies and log decisions to OPA and if applicable, decide how to load data into OPA.
Service Integration. If you are using a network proxy that intercepts all network traffic going to your services (e.g. Envoy, Linkerd, Kong, ...) you can configure your network proxy to call out to OPA without modifying your .Net service. If you're not using a network proxy, modify your .Net services to make HTTP callouts when your services need policy decisions, using a library where possible to minimize the impact on individual services. The integration page shows how for Java Spring and PHP.
Tim Hinrichs' answer above is on point. However, to add to it here are some specific solutions. Out of the 2 solutions below, I would recommend using the REST API and ASP.NET middleware. Also, while OPA can theoretically be used as an Authentication tool, I would advise against it. It's purpose is Authorization.
Use ASP.NET Authorization Middleware
Firstly, OPA would be running either as it's own service, as a sidecar in k8's, or in a Docker container. OPA's documentation does a good job showing examples on how to implement that so I won't go into specifics.
Here you would create a .NET service that queries OPA's Rest API.
Here is a a complete example here
Here is Microsoft's documentation on using middleware
This is what the middleware would look like.
using System.Net;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
namespace Authz.Opa
{
public class OpaAuthzMiddleware
{
private const string ForbiddenMessage = "Forbidden";
private readonly RequestDelegate _next;
private readonly IOpaService _opaService;
public OpaAuthzMiddleware(RequestDelegate next, IOpaService service)
{
_next = next;
_opaService= service;
}
public async Task InvokeAsync(HttpContext context)
{
var enforceResult = await _opaService.RunAuthorizationAsync(context);
if (!enforceResult)
{
context.Response.StatusCode = (int)HttpStatusCode.Forbidden;
await context.Response.WriteAsync(ForbiddenMessage);
return;
}
await _next(context);
}
}
}
and you would implement it in your startup like this
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
namespace Sample
{
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
services.AddRouting();
services.AddSingleton<IOpaService, OpaService>();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseRouting();
app.UseMiddleware<OpaAuthzMiddleware>();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
}
Use OPA's Wasm compilation
OPA has tooling that can compile Rego policies into executable Wasm modules. They provide documentation here.
It's currently under development, but there is an example on using this in .NET here. Looking at the discussions under that repo's Issues section, it looks like they're still working out some things.
You would need to use one of the available .NET libraries to read the compiled Wasm files, but this is considered to be the fastest evaluation method that OPA offers.

How to bypass calls to the OwinStartup class for WEB API 2 requests that are part of ASP.NET MVC 5 application?

I am using OpenId connect protocol for setting up the AzureAD authentication for ASP.NET MVC5 application. It is working fine as expected. The same code base has WEB API 2 controllers which is used by another angular app. The WEB API endpoints are setup with allow anonymous access in the root web.config file which is common for both ASP.NET MVC5 app and the WEB API 2 controllers.
There is a Startup.cs page which contains the logic for the OpenID connect protocol implementation.
Startup.cs:
[assembly: OwinStartup(typeof(MyApp.CMS.Web.Startup))]
namespace MyApp.CMS.Web
{
public partial class Startup
{
public void Configuration(IAppBuilder app)
{
// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=316888
ConfigureAuth(app);
}
}
}
The namespace for the WEB API 2 Controllers is MyApp.CMS.Web.Controllers.ApiControllers
Here I want to stop execution of all the calls that are made to Startup.cs whenever any WEB API endpoint is invoked.
Can anyone help me to provide their guidance to fix this issue.
The WEB API endpoints are setup with allow anonymous access in the root web.config file
Actually, no - that is not possible.
Both MVC and Web API use HTTP modules as endpoints (that end up calling controller action methods). The ASP.NET web.config settings only apply to physical files and folders on the web server. MVC and Web API bypass these web.config settings so they have no effect.
Here I want to stop execution of all the calls that are made to Startup.cs whenever any WEB API endpoint is invoked.
The code in Startup.cs is only executed one time per application start (or app pool refresh), so the only thing that takes place here are application-wide settings. It doesn't take part in the per-request authorization of controller actions.
If you want to control access to Web API controller action methods, you should use [Authorize] attribute from the System.Web.Http namespace (or a customized subclass of it). You will also need to setup Authorization with Web API for [Authorize] attribute to function.
To apply authorization to the entire Web API, you can register System.Web.Http.AuthorizeAttribute as a global filter.
GlobalConfiguration.Configuration.Filters.Add(new System.Web.Http.AuthorizeAttribute());
MVC has its own [Authorze] attribute and completely ignores the one from Web API, so this setting will have no effect on MVC.

SignalR v2 with load balancer

I am pretty new to SignalR and have been going through some tutorials as I've been tasked with upgrading our current implementation.
We've got an ASP.NET MVC application which uses SignalR (version 1.x). The application is in our F5 load-balanced cloud environment. So we have multiple sites (for different customers) using the same load balancer. To make the SignalR calls servers-side, we use the HubConnection from the Microsoft.ASPNET.SignalR.Client namespace and create a proxy like this (full example here):
var hubConnection = new HubConnection("http://www.contoso.com/");
IHubProxy stockTickerHubProxy = hubConnection.CreateHubProxy("StockTickerHub");
stockTickerHubProxy.On<Stock>("UpdateStockPrice", stock => Console.WriteLine("Stock update for {0} new price {1}", stock.Symbol, stock.Price));
await hubConnection.Start();
Where http://contoso.com/ is the current customer's site URL.
We are looking to upgrade to the latest SignalR (version 2.x) and I am wondering if it is necessary to even use the HubConnection. Even though the article above specifies version 2, it does mention:
This document provides an introduction to using the Hubs API for SignalR version 2 in .NET clients, such as Windows Store (WinRT), WPF, Silverlight, and console applications.
This is a web application with a regular class library back-end for data access. Taking a look at this tutorial, I don't see anything about HubConnection (it also doesn't mention load balancing). Consider the following, from the Chat tutorial:
public class ChatHub : Hub
{
public void Send(string name, string message)
{
// Call the addNewMessageToPage method to update clients.
Clients.All.addNewMessageToPage(name, message);
}
}
Then, in Statup.cs:
public class Startup
{
public void Configuration(IAppBuilder app)
{
// Any connection or hub wire up and configuration should go here
app.MapSignalR();
}
}
So my question is, are we using SignalR properly? If not, what considerations/modifications need to be made when running a load-balanced application which uses SignalR (v2.x)? I haven't been able to find much regarding load balancing, etc.
Or is this a job for Groups?
You don't need to change anything structural. Have a look at the signalr redis scaleout, or any other scaleout option. Basically you need to install an additional package and ms opentech redis to do load balancing. So the scaleout will make sure that each request is sent over a message bus, making multiple servers possible.

Importance of Web API Controller comparing with Class Library project?

I am new to MVC 4.0. I recently underwent WEB API Controller.
AS per this link, we can reuse our function at multiple places in the form of Web API Controller that returns data instead of View. Sorry for mentioning so obvious things.
My Question is : Web API Controller is only about reusability of the function in some website/Andriod etc ? If so, couldn't we use Class Library Project?
A Web API Controller is a controller for a web service, which is very different from a Class Library project which you include in a project.
A web service is something you communicate with, you don't include it as an assembly in your project.
You can not publish your class library for public use while in case of web service you do.
You provide the URL of web service so that anyone can consume it while class library can be used within your project only.
Additional to above, web api has so many features that you can find at http://www.asp.net/web-api

Examples of ASP.Net MVC 2 - WCF/WSDL - using IoC methodology

We here at my company are just about to get going on ASP.Net MVC 2 for our UI to interface a backend totally SOA with WCF/WSDL. I have looked at various books examples of how to totally make the applicalion loosely coupled from the Domain perspective using the IoC containers e.g. Unity or Castle (looks to be the way to go !) ...BUT Are there any GOOD examples though of this in using WSDL calls ...we are not yet using oData...just the standard wsdl.
Any help, hints appreciated...
The reference application for asp.net mvc NerdDinner is a good place to start http://weblogs.asp.net/shijuvarghese/archive/2009/03/12/applying-dependency-injection-in-asp-net-mvc-nerddinner-com-application.aspx
The Service Contract for each of the WCF services for which you do an "Add Service Reference" will be an interface. Simply program against that interface.
So you have a ISomeService service contract. Pass an instance of that contract to the classes that need to interact with it:
public SomeClass(ISomeService service)
{
this._service = service;
}
public List<Something> GetSomething()
{
return _service.GetSomething();
}
Now you can either pass a SomeServiceClient instance, or a SomeMockService instance to the class.

Resources