12

I am part of a team working on a large application. I am a new addition to this team and am building a new piece of the app. As part of this process, I've created a WebApi application that will expose some HTTP endpoints through which I will retrieve information about the app.

Due to conditions it would take far too long to explain, I'd like to get the WebApi project to build in another directory, specifically ..\bin\Server\Debug\ as this is where most of the other portions of the app build to. I would not bother except that the app tried to use files that are found based on the working directory which is currently wrong for my WebApi app.

I tried changing it in the project settings and now I get this error: Could not load type WebApiApplication

My Googling has turned up little help thus far. Anyone know how to resolve this?

SethGunnells
  • 1,269
  • 1
  • 12
  • 19
  • I'm having the same issue. Does anyone have any idea how to debug this? Why is a `WebApiApplication` required to have an output build directory of `bin\`? – Brett Oct 22 '15 at 20:08
  • This may be a dense question but did you rebuild all your solution? Did you manually copy any assemblies into your bin from other places? – Ross Bush Oct 22 '15 at 20:14
  • @Irb Yes, I rebuilt the solution. And no I haven't copies any assemblies into bin from other places. – Brett Oct 22 '15 at 20:17
  • When you click on the referenced file, JDX.WebApi.WebApiApplication, in your project, is the Copy Local property in the property explorer set to True? Did you recently rename your project? – Ross Bush Oct 22 '15 at 20:43
  • Are the "the other portions of the app" assemblies on which JDX.WebApi.WebApiApplication is dependent? – Pete Klein Oct 29 '15 at 19:35
  • You mention "conditions it would take far too long to explain". To get an answer to your specific problem, I think you should explain. – Pete Klein Oct 29 '15 at 19:41

3 Answers3

8

Try adding a runtime probing path in the configuration:

<configuration>
   <runtime>
      <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
         <probing privatePath="bin\server\Debug;"/>
      </assemblyBinding>
   </runtime>
</configuration>

In addition to above step and to get rid of globa.asax error. Open the mark up of Global.asax file and Add follow line on the top.

<%@ Assembly Name="<you_web_app_assembly_name_here>" %>

Now you'll start getting the error of System.web or BindingProvider not found etc. There's weird fix for it start adding assemblies to assembly tag under compilation.

 <compilation debug="true" targetFramework="4.5" optimizeCompilations="false">
      <assemblies>
        <add assembly="Microsoft.AspNet.Identity.Core, Version=2.2.1, PublicKeyToken=31bf3856ad364e35" />
        <add assembly="System.Web.Mvc, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
        <add assembly="System.Web.Abstractions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
        <add assembly="System.Web.Helpers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
        <add assembly="System.Web.Routing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
        <add assembly="System.Web.WebPages, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
        <add assembly="System.Web.Optimization, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
      </assemblies>
</compilation>

You'll get few more errors like this but this will get you going.

Reason: The problem I see is that there's an option to change the output path but Asp.net does on the fly compilation. Which why the error are compilation related when you try to run the website. Somewhere the run time compilation only look in \bin folder and which is why we have to specify every assembly that the project is referencing to.

Update - Unfortunately you can not change the bin directory. After looking at all options and digging found that bin folder of Asp.net web project is not ordinary binary output folder. It's a share code folder from where the binaries are referenced directly in the project.

The binaries are compiled when a first request is received by webserver for Asp.net application. And bin folder is only use as shared binary references folder and not the actual output folder/directory. The actual output folder of On-the-fly compilation in Asp.net is default set to %SystemRoot%\Microsoft.NET\Framework\<versionNumber>\Temporary ASP.NET Files that you can change ofcourse from compilation tag attribute [tempDirectory][3] in your web.config.

After all these research I came to this conclusion that the option for changing the directory from project -> properties -> Build -> Bin is appearing because of Asp.net website project template. This gives the user same look'n feel as any other project. But the functionality of asp.net website remains the same. The Bin folder still works as it used to work in old website template of Asp.net.

vendettamit
  • 14,315
  • 2
  • 32
  • 54
  • Would I have to change this by hand to `bin\server\Release` for running in `Release` mode? – Brett Oct 22 '15 at 20:27
  • you can use the transform feature to avoid manual changes for release. under web.config there would be web.debug.config and web.release.config. put "bin\server\Debug;" in debug and "bin\server\Release;" in release configuration file. – vendettamit Oct 22 '15 at 20:29
  • Just tried it and I'm still seeing the same error. I made sure that my "Output Path" was set to `bin\server\Debug`, and then added the above code to `web.debug.config` (and the respective change for release). – Brett Oct 22 '15 at 20:36
  • @Brett Updated my answer. – vendettamit Oct 22 '15 at 21:37
1

You cannot change the output directory of an asp.net application due to IIS security restrictions, this is why it is not working.

If you are trying to manage dlls due to DI, copy all other satellite dlls into bin folder of your main asp.net app

Serdar
  • 71
  • 1
  • 3
0

You can try copying the dll with the after build target. First change the output path back to what it was if you changed it before. Then add some code like this in your project file.

<target name="AfterBuild">     
 <copy destinationfolder="..\bin\Server\Debug\" overwritereadonlyfiles="true" sourcefiles="$(OutputPath)\$(AssemblyName).dll" />   
 <copy destinationfolder="..\bin\Server\Debug\" overwritereadonlyfiles="true" sourcefiles="$(OutputPath)\$(AssemblyName).pdb" />    
 <copy destinationfolder="..\bin\Server\Debug\" overwritereadonlyfiles="true" sourcefiles="$(OutputPath)\$(AssemblyName).xml" />  
</target>

This will put the built dll in to the folder specified in destinationfolder. I usually use this for class libraries but i don't see why it would not work for a web api project

You can check out my blog post on this if you like.

http://torontoprogrammers.blogspot.com/2014/11/msbuild-targets-and-tasks.html

Aaron
  • 1,361
  • 1
  • 13
  • 30