2

I have some WebApi controllers inside a class library and i wanna host them inside IIS. I know the solution for Self-Hosting inside a console application or windows service but that's only good for local use. How could I resolve the controllers assembly inside an Asp.Net Web/WebApi application which is actually ideal for hosting in IIS?

I am looking for something like this approach only with different hosting scenario: http://www.strathweb.com/2012/06/using-controllers-from-an-external-assembly-in-asp-net-web-api

Siavash Rostami
  • 1,883
  • 4
  • 17
  • 31

1 Answers1

1

The easiest way I know to do this is by leveraging Attribute Routing

Example

Take for example, a sample class library that contains an ApiController. Using Attribute Routing, we can decorate the class with the route.

//Inside API controller class library
[RoutePrefix("Persons")]
public class PersonController : ApiController
{
    [Route("")]
    public List<Person> GetAll()
    {
        List<Person> results = new List<Person>();

        try
        {
            //TODO: Call Data Access Layer
            //FORNOW: Mock up some data
            results.Add(new Person() { Name = "Ryan C" });
            results.Add(new Person() { Name = "Siavash R" });
        }
        catch
        {
            //TODO: Handle error
        }

        return results;
    }
}

The above code would respond to an HTTP Request of /Persons once properly routed.

Now in your WebApi project, which will be hosted in IIS, you need to do the following:

Add a reference to your class library

I know this is probably a 'duh' but just putting this here as a formality. You'll need to add the reference to your API Controller class library in your WebApi project.

Create a registration method

Either in App_Start\RouteConfig.cs or in a new App_Start\WebApiConfig.cs, you make a call to MapHttpAttributeRoutes();, like so:

//Inside App_Start\WebApiConfig.cs
public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        // Map all Web API routes
        config.MapHttpAttributeRoutes();
    }
}

The ASP.NET framework is smart enough to search through any referenced assemblies and look for public ApiController-derived classes, and in this case, ones decorated for Attribute Routing.

Call registration method in Global.asax

The last step is to actually call the registration method in the Global.asax file:

//Inside Global.asax
public class WebApiApplication : System.Web.HttpApplication
{
    protected void Application_Start()
    {
        GlobalConfiguration.Configure(WebApiConfig.Register);
    }
}

After that, you should be good to go! I tested it locally, building a complete example and it works just fine. If needed I can post my sample project to github, but the above code is the key points.

Making the call to http://localhost:xxxx/Persons/ resulted this:

<ArrayOfPerson xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/Ryancdotnet.WebApiClassLib.Model">
  <Person>
    <Name>Ryan C</Name>
  </Person>
  <Person>
    <Name>Siavash R</Name>
  </Person>
</ArrayOfPerson>

For reference, in case you need it, my ApiController class library used these Nuget packages. I'm not sure which ones were exactly necessary, but these were enough for the class library.

<?xml version="1.0" encoding="utf-8"?>
<packages>
  <package id="Microsoft.AspNet.WebApi.Client" version="5.2.3" targetFramework="net46" />
  <package id="Microsoft.AspNet.WebApi.Core" version="5.2.3" targetFramework="net46" />
  <package id="Microsoft.Bcl" version="1.1.10" targetFramework="net46" />
  <package id="Microsoft.Bcl.Build" version="1.0.14" targetFramework="net46" />
  <package id="Microsoft.Net.Http" version="2.2.29" targetFramework="net46" />
  <package id="Newtonsoft.Json" version="6.0.4" targetFramework="net46" />
  <package id="System.Web.Http.Common" version="4.0.20126.16343" targetFramework="net46" />
</packages>

Happy API-ing!

ryancdotnet
  • 2,015
  • 16
  • 33