user1019872
user1019872

Reputation: 659

Base controller from another class library doesn't working in web api

I have two Web API projects and I have a MarketController and I need to extend the Api controller so I did it.

I created a BaseController class and inherit from ApiController like this:

public class BaseController:ApiController { }

so far so good, it's working fine:

public class MarketController : BaseController
{
    public MarketController() : base()
    {
    }

    // GET api/<controller>
    public IEnumerable<string> Get()
    {
        return new string[] { "value1", "value2" };
    }
}

But I wanted to do it in another class library called BLL, so I moved the BaseController class to the BLL class library and I referenced it in the Web API project.

When I did this, the api stopped working.

The response is :

{
    "Message": "No HTTP resource was found that matches the request URI someurl/api/market.",
    "MessageDetail": "No type was found that matches the controller named 'market'."
}

Upvotes: 2

Views: 3318

Answers (2)

Tom Hollander
Tom Hollander

Reputation: 693

No need to implement custom ControllerFactory or AssemblyResolver classes. This scenario will "just work" provided you add the Microsoft.AspNet.WebApi.Core nuget package to the assembly containing the base class.

In my case I'd just added a reference to the System.Web.Http.dll which will compile, but the controllers will not load properly. Adding the Nuget package got everything working with no code changes.

Upvotes: 2

Ajay Kelkar
Ajay Kelkar

Reputation: 4621

By default MVC looks for all controllers in same assembly of mvc application. The default controller factory creates controller instance based on string 'ControllerName+Controller' like MarketController where market comes from url market/actionname.It will look for MarketController in the same assembly as mvc application.

To put controller in separate assembly you will have to create your own controller factory or you will have to specify assembly name is app start.

Once you've created your own custom ControllerFactory, you add the following line to Application_Start in global.asax to tell the framework where to find it:

ControllerBuilder.Current.SetControllerFactory(new MyControllerFactory());

Or for simple cases like yours you can do this :

routes.MapRoute(
    "Default",
    "{controller}/{action}/{id}",
    new { controller = "Home", action = "Index", id = "" },
    new[] { "BLLAssembly.Controllers" }
);

Here BLLAssembly.Controllers is namespace for your BaseController in BLL assembly.

There is one more advanced way using custom assembly resolver ,i.e IAssembliesResolver The below article tells how to do this with Web Api also,

http://www.strathweb.com/2012/06/using-controllers-from-an-external-assembly-in-asp-net-web-api/

Upvotes: 1

Related Questions