Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WebApi controller using a class library

I'm trying to create a system that will allow me to host a "WebAPI" website either through a web application or through a windows service. To this end I want all my buisness logic to be contained within one class library so that I can reference this in both my windows service and my "web" (IIS) service.

My current idea is using the self hosted options included in HttpSelfHostServer. For the web end I would just create a standard webapi website and add some reference to my class library.

What I have found is that if I have the controller in the same namespace as the HttpSelfHostServer it works correctly but as soon as the controller is within an external class library the server can no longer resolve the route to my control / action.

My code:

Windows service:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using System.Reflection;
using System.IO;

using System.Web.Http.SelfHost;
using System.Web.Http;
using System.Web.Http.Dispatcher;

using WebApiClasses;
using WebApiClasses.Controllers;

namespace WebAPISelfHost
{
    public partial class Service1 : ServiceBase
    {
        private HttpSelfHostServer _server;
        private readonly HttpSelfHostConfiguration _config;
        public const string ServiceAddress = "http://localhost:8080";

        public Service1()
        {
            InitializeComponent();

            _config = new HttpSelfHostConfiguration(ServiceAddress);

            //AssembliesResolver assemblyResolver = new AssembliesResolver();
            //_config.Services.Replace(typeof(IAssembliesResolver), assemblyResolver);

            _config.Routes.MapHttpRoute("DefaultApi",
                "api/{controller}/{id}",
                new { id = RouteParameter.Optional });

        }

        protected override void OnStart(string[] args)
        {
            _server = new HttpSelfHostServer(_config);
            _server.OpenAsync();
        }




        protected override void OnStop()
        {
            _server.CloseAsync().Wait();
            _server.Dispose();
        }
    }

    //public class TestController : ApiController
    //{
    //    public string Get()
    //    {
    //        return "This is an internal test message.";
    //    }
    //}

    class AssembliesResolver : DefaultAssembliesResolver
    {
        public override ICollection<Assembly> GetAssemblies()
        {
            ICollection<Assembly> baseAssemblies = base.GetAssemblies();
            List<Assembly> assemblies = new List<Assembly>(baseAssemblies);

            // Add whatever additional assemblies you wish

            var controllersAssembly = Assembly.LoadFrom(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + @"\WebApiClasses.dll");
            baseAssemblies.Add(controllersAssembly);
            return assemblies;
        }
    }
}

Controller:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.Web.Http;

namespace WebApiClasses.Controllers
{
    public class TestController : ApiController
    {
        public string Get()
        {
            return "hello from class library";
        }
    }
}

When I try to navigate to: "http://localhost:8080/api/" I get:

No HTTP resource was found that matches the request URI 'http://localhost:8080/api/'. No type was found that matches the controller named 'Test'.

Any suggestions? I think I should be able to do this.

like image 899
TheKingDave Avatar asked Dec 18 '12 17:12

TheKingDave


Video Answer


2 Answers

I have a similar problem and i do the following actions and i solve it.

  1. First of all add the reference from the external class library in the api project.
  2. The controller must inherit from ApiController
  3. The controller class must have public acess modifier and must the controller name to end with Controller.For example TestController ,EmployeeController etc
  4. And the very important the nuget packages must have the same version.

I also sugget the using of attributes like [HttpGet],[HttpPost]

like image 180
dimath Avatar answered Oct 11 '22 23:10

dimath


Have a look at this article http://www.strathweb.com/2012/06/using-controllers-from-an-external-assembly-in-asp-net-web-api/

In it they describe how to load in extra assemblies with controllers in them.

like image 33
AndyD Avatar answered Oct 11 '22 23:10

AndyD