Blog coding and discussion of coding about JavaScript, PHP, CGI, general web building etc.

Tuesday, February 2, 2016

How to configure Web Api 2 to look for Controllers in a seperate project? (just like I used to do in Web Api)

How to configure Web Api 2 to look for Controllers in a seperate project? (just like I used to do in Web Api)


I used to place my controllers into a separate Class Library project in Mvc Web Api. I used to add the following line in my web api project's global.asax to look for controllers in the seperate project:

ControllerBuilder.Current.DefaultNamespaces.Add("MyClassLibraryProject.Controllers");  

I never had to do any other configuration, except for adding the above line. This has always worked fine for me.

However I am unable to use the above method to do the same in WebApi2. It just doesn't works. The WebApi2 project still tries to find the controllers in its own project's controllers folder.

Any ideas?

-- Giving little summary update after 2 months (As I started bounty on this):

I have created a WebApiOne solution, it has 2 projects, the first one is WebApi project, and the second is a class library for controllers. If I add the reference to the controllers class library project into the WebApi project, all works as expected. i.e. if i go to http://mydevdomain.com/api/values i can see the correct output.

I have now create a second project called WebApiTwo, it has 2 projects, the first one is WebApi2 project, and the second is a class library for controllers. If I add the reference to the controllers class library project to the WebApi2 project, it doest NOT work as expected. i.e. if i go to http://mydevdomain.com/api/values i get "No type was found that matches the controller named 'values'."

for the first project i am not doing any custom settings at all, i do NOT have:

ControllerBuilder.Current.DefaultNamespaces.Add("MyClassLibraryProject.Controllers");  

in my global.asax, and i have not implemented any custom solutions proposed by StrathWeb in two of his blog posts, as i think its not applicable any more; because all works just by adding the reference of the controller project to the WebApi project.

So i would expect all to work same for WebApi2 ... but its not. Has any one really tried doing this in WebAPi2 ???

Answer by justmara for How to configure Web Api 2 to look for Controllers in a seperate project? (just like I used to do in Web Api)


Are you sure that your referenced assembly was loaded BEFORE IAssembliesResolver service called? Try to insert some dummy code in your application, something like

var a = new MyClassLibraryProject.Controllers.MyClass();

in configuration method (but don`t forget, that compiler can "optimize" this code and totally remove it, if "a" is never used). I've had similar issue with assembly loading order. Ended up with force loading dependent assemblies on startup.

Answer by DavidG for How to configure Web Api 2 to look for Controllers in a seperate project? (just like I used to do in Web Api)


I have just confirmed that this works fine. Things to check:

References: Does your main Web API project reference the external class library?

Routing: Have you set up any routes that might interfere with the external controllers?

Protection Level: Are the controllers in the external library public?

Inheritance: Do the controllers in the external library inherit from ApiController?

Versioning: Are both your Web API project and class library using the same version of the Web API libraries?

If it helps, I can package up my test solution and make it available to you. Also, as a point to note, you don't need to tell Web API to find the controllers with the line you added to Global.asax, the system finds the controllers automatically provided you have them referenced.

Answer by Nikola Radosavljevi for How to configure Web Api 2 to look for Controllers in a seperate project? (just like I used to do in Web Api)


It should work as is. Checklist

  • Inherit ApiController
  • End controller name with Controller. E.g. ValuesController
  • Make sure WebApi project and class library project reference same WebApi assemblies
  • Try to force routes using attribute routing
  • Clean the solution, manually remove bin folders and rebuild
  • Delete Temporary ASP.NET Files folders. WebApi and MVC cache controller lookup result

This controller:

[RoutePrefix("MyValues")]  public class AbcController : ApiController  {      [HttpGet]      [Route("Get")]      public string Get()      {          return "Ok!";      }  }  

matches this url:

http://localhost/MyValues/Get (note there is no /api/ in route because it wasn't specified in RoutePrefix.


Controller lookup caching: This is default controller resolver. You will see in the source code that it caches lookup result.

///   /// Returns a list of controllers available for the application.  ///   /// An  of controllers.  public override ICollection GetControllerTypes(IAssembliesResolver assembliesResolver)  {      HttpControllerTypeCacheSerializer serializer = new HttpControllerTypeCacheSerializer();        // First, try reading from the cache on disk      List matchingTypes = ReadTypesFromCache(TypeCacheName, IsControllerTypePredicate, serializer);      if (matchingTypes != null)      {          return matchingTypes;      }  ...  }  

Answer by muluhumu for How to configure Web Api 2 to look for Controllers in a seperate project? (just like I used to do in Web Api)


When using AttributeRouting it is easily forgettable to decorate your methods with the Route Attribute, especially when you are using the RoutePrefix Attribute on your controller class. It seems like your controller assembly wasn't picked up by the web api pipeline then.

Answer by user1821052 for How to configure Web Api 2 to look for Controllers in a seperate project? (just like I used to do in Web Api)


Was running into same scenario and @justmara set me on the right path. Here's how to accomplish the force loading of the dependent assemblies from @justmara's answer:

1) Override the DefaultAssembliesResolver class

public class MyNewAssembliesResolver : DefaultAssembliesResolver  {      public virtual ICollection GetAssemblies()      {            ICollection baseAssemblies = base.GetAssemblies();          List assemblies = new List(baseAssemblies);          var controllersAssembly = Assembly.LoadFrom(@"Path_to_Controller_DLL");          baseAssemblies.Add(controllersAssembly);          return baseAssemblies;        }  }  

2) In the configuration section, replace the default with the new implementation

config.Services.Replace(typeof(IAssembliesResolver), new MyNewAssembliesResolver());  

I cobbled this syntax together using pointers from this blog:

http://www.strathweb.com/2013/08/customizing-controller-discovery-in-asp-net-web-api/

As others have said, you know if you are running into this issue if you force the controller to load by directly referencing it. Another way is to example the results of CurrentDomain.GetAssemblies() and see if your assembly is in the list.

Also: If you are self-hosting using OWIN components you WILL run into this. When testing keep in mind that the DefaultAssembliesResolver will NOT kick in until the first WebAPI request is submitted (it took me awhile to realize that).

Answer by Igor Lankin for How to configure Web Api 2 to look for Controllers in a seperate project? (just like I used to do in Web Api)


Apart from what has been said already:

Make sure you don't have two controllers of the same name in different namespaces.

Just had the case where one controller (foo.UserApiController) should be partially migrated to a new namespace (bar.UserApiController) and URI. The old controller was mapped by convention to /userapi, the new one was attribute-routed via RoutePrefix["api/users"]. The new controller didn't work until I renamed it to bar.UserFooApiController.

Answer by CodeCabbie for How to configure Web Api 2 to look for Controllers in a seperate project? (just like I used to do in Web Api)


If your class library is built with EF then make sure you have the connection string specified in the App.config for the class library project, AND in the Web.config for your Web API MVC project.

Answer by Ryios for How to configure Web Api 2 to look for Controllers in a seperate project? (just like I used to do in Web Api)


You need to tell webapi/mvc to load your referrenced assembly. You do that with the compilation/assemblies section in your web.config.

                  

Simple as that. You can do it with code the way @user1821052 suggested, but this web.config version will have the same effect.


Fatal error: Call to a member function getElementsByTagName() on a non-object in D:\XAMPP INSTALLASTION\xampp\htdocs\endunpratama9i\www-stackoverflow-info-proses.php on line 72

0 comments:

Post a Comment

Popular Posts

Powered by Blogger.