10

I have an ASP MVC 4 project. It started as MVC 1, so it uses the old-style ASPX/ASCX views. I want to have the views compile at build time, mainly to get compile time error checking (and also, importantly, to have the errors show directly in Visual Studio). I'm developing in Visual Studio Pro 2015 using IIS Express as debug server.

As per both msdn, Haacked and questions here such as this I have set the following my .vbproj:

<MvcBuildViews>true</MvcBuildViews>

and also in my .vbproj created a task

<Target Name="BuildViews" Condition="'$(MvcBuildViews)'=='true'" AfterTargets="Build">
  <Message Importance="normal" Text="Precompiling views" />
  <AspNetCompiler VirtualPath="temp" PhysicalPath="$(WebProjectOutputDir)" />
</Target>

However, that gives me an error when trying to build:

'/temp' is not a valid IIS application.

As a file it just references ASPNETCOMPILER

I've tried various alternatives as VirtualPath - I have the project configured to run as a sub-directory /local in dev so I tried that, and the site names from the config in the .vs folder and nothing works.

Should I change the VirtualPath (and if so to what) or is there some other config missing for temp to work?

Edit

Also, I get the same error running a command line MSBuild. For my actual production systems, I have a script which does a build using command line MSBuild then moves the built package to the product servers and deploys. So that won't have either IIS express (or IIS running) when it's built. Do you need a web server connected just to compile the views?

Edit 2

I am confused by the need for the virtulPath here and the apparent connection to the web server. Some of the suggested solutions involve configuring IIS. IIS Express (which I use for debugging) isn't even necessarily running until after a successful build as I understand it? Anyway, my application runs in a virtual directory quite happily (/local in debug mode) but using that as a value doesn't work. If it matters, this is the relevant part of the applicationhost.config in the .vs folder in my project (I tried putting the same paths into the applciationhost.config in Documents/IIS Express):

 <site name="CarWeb-Site" id="2">
    <application path="/" applicationPool="Clr4IntegratedAppPool">
        <virtualDirectory path="/" physicalPath="C:\Users\adam.conway\Documents\My Web Sites\CarWeb-Site" />
    </application>
    <application path="/local" applicationPool="Clr4IntegratedAppPool">
        <virtualDirectory path="/" physicalPath="filesystem path to my project" />
    </application>
    <bindings>
        <binding protocol="http" bindingInformation="*:57047:localhost" />
        <binding protocol="http" bindingInformation="*:57047:*" />
    </bindings>
</site>

So I really don't understand why just VirtualPath="/" doesn't work, since that's the virtual path referenced in those configs.

While my primary aim here is showing view errors in Visual Studio (and I would accept an answer limited to that) it is also the case that I build for production environments using MSBuild on a machine which doesn't necessarily even have IIS installed.

Community
  • 1
  • 1
Adam
  • 6,539
  • 3
  • 39
  • 65
  • Create Temp directory in your solution with write access to dotnet process. While building project it is creating temporaty files and as per error it is not able to find temp directory/virtual path. Once it finds it check for write access is there or not. Hope this helps! – Amit Feb 23 '17 at 09:14
  • @Amit: Doesn't work. Tried it. Isn't it asking for a virtual path. I.e. somehow relative to the URL? I tried using `$(OutputPath)` as the _VirtualPath_ (which it must have write access to, since that's where it creates the .dll) and also `$(IntermediateOutputPath)` and got the same error. (Well, the path change: _'/bin/' is not a valid IIS application._ and _'/obj/Debug/' is not a valid IIS application._) – Adam Feb 23 '17 at 09:57
  • Instead of IIS express can you try with IIS and see if it works? Check if this setting helps in IISExpress https://gist.github.com/paigecook/876258 – Amit Feb 23 '17 at 10:02
  • @Amit: i'd much rather stick with ISS Express than add another level of config to my environment. Also, I get the same error running a command line msbuild. For my actual production systems I have a script whcih does a build using command line msbuild then moves the built package to the product severs and deploys. So that won't have either IIS express or IIS running when it's built. Do you need a web server connected just to compile the views? (I'll add this to the question) – Adam Feb 23 '17 at 11:27
  • It is not for all that. It is just to troubleshoot with the settings. Have you tried setting gist.github.com/paigecook/876258 ? – Amit Feb 23 '17 at 12:01
  • @Amit: the problem is how it interprets _Virtualpath_ not _PhysicalPath_ I think. The references in the question also say not to use what you list in the gist as not working, but suggest instead what I have. Trying the gist I just get _directory does not exist_ for Web within my project. If I create that directory it builds without errors - but does not compile the views because I've pointed it at an empty directory! So I still don't get the compile-time checking of the views I want. – Adam Feb 23 '17 at 14:00
  • Build without error is not sign of view got compiled? – Amit Feb 23 '17 at 18:04
  • No. If I refactor a class so as to leave an error in a view then the error doesn't show until i open the view. Plus, think about it. I've pointed the compile at an empty folder, so why would anything compile? – Adam Feb 23 '17 at 18:51
  • Do you already tried adding this ..\bin after true – jomsk1e Feb 27 '17 at 11:12
  • @jomsk1e: Tried it now, and doesn't help. Again, isn't that about finding the views to compile, when the error is about the _VirtualPath_? – Adam Feb 27 '17 at 11:32
  • Have you tried a `VirtualPath` of blank or just `/`? – DavidG Mar 02 '17 at 00:53
  • Leaving it empty is the same as not including it at all - it complains that either VirtualPath or MetaBasePath must eb specified. Tried "/" but it gave the same error, that's it's not a valid IIS application. – Adam Mar 02 '17 at 13:44
  • @Adam have you tried using any folder address combined with `~`, for example `"~/temp"`? Also, have you take a look at http://stackoverflow.com/questions/32694217/visual-studio-2015-adding-virtual-directory-not-possible – Armin Mar 05 '17 at 07:56
  • ~ doesn't work. I'm grateful for the help, but if you think you have an answer can you post it as an answer:) Doesn't seem right to be suing the comments like this. – Adam Mar 05 '17 at 22:34

2 Answers2

4

AspNetCompiler calls aspnet_compiler.exe (https://msdn.microsoft.com/en-us/library/ms229863.aspx?f=255&MSPPError=-2147217396). In Visual Studio Error List calls to this exe are displayed as ASPNETCOMPILER.

I recommend you to enable diagnostic level logging https://msdn.microsoft.com/en-us/library/jj651643.aspx, then search build log for aspnet_compiler.exe string and check what parameters (expecially what path) are being used when calling aspnet_compiler.exe. Also you can copy from log & manually call aspnet_compiler.exe in cmd.exe.

Most probably problem is in PhysicalPath attribute, not in VirtualPath, it seems VirtualPath attribute does not affect build. Check those answers:

If you need separate paths for MSBuild and Visual Studio you can use this technique http://web4.codeproject.com/Articles/156989/Resolve-temp-global-asax-error-ASPPARSE-Could?display=Print

Community
  • 1
  • 1
snautz
  • 521
  • 4
  • 5
  • Thank you! it seems `$(WebProjectOutputDir)` isn't defined at all. The log is just giving the command as `C:\Windows\Microsoft.NET\Framework\v4.0.30319\aspnet_compiler.exe -v /` - surely there should be a -p and a path there! – Adam Mar 06 '17 at 13:24
  • 1
    Changing to `` seems to work. The examples had `$(ProjectDir)\..\$(ProjectName)` but I'm not sure why, since that just resolves to ProjectDir... – Adam Mar 06 '17 at 13:30
  • @Adam - `VirtualPath="/"` worked for me. I recommend you'd add that as an answer, it deserves to be more visible (I would have edited it into this answer, but the answer is too general). – Kobi Jul 31 '17 at 09:05
2

Based on @snautz answer, the line I actually use that works for me is

<AspNetCompiler VirtualPath="/" PhysicalPath="$(ProjectDir)" />

Many of the online examples used $(ProjectDir)\..\$(ProjectName) as the PhysicalPath but I'm not sure why, since that just resolves to $(ProjectDir) ...

Adam
  • 6,539
  • 3
  • 39
  • 65