2

We've been trying to pre-compile the views for our application to improve the render times on initial form display.

We're using Visual Studio 2017, MVC 5, MS Membership for security logins.

When Publishing to the web application site without 'Precompile during publishing' set it all builds and the application runs as expected with a login form shown.

When the 'Precompile during publishing' is set on then it builds ok.

But when starting the application we get a 'HTTP Error 404.0 - Not Found' error and no login screen shown !

I've checked the folders' security, location paths permissions allow All Users.

When publishing with Precompile set on I get the following warnings;

2>ASPNETCOMPILER(0,0): Warning : The following assembly has dependencies on a version of the .NET Framework that is higher than the target and might not load correctly during runtime causing a failure: Microsoft.ReportViewer.WebDesign, Version=14.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91. The dependencies are: System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089. You should either ensure that the dependent assembly is correct for the target framework, or ensure that the target framework you are addressing is that of the dependent assembly. 2>ASPNETCOMPILER(0,0): Warning : The following assembly has dependencies on a version of the .NET Framework that is higher than the target and might not load correctly during runtime causing a failure: Microsoft.ReportViewer.Design, Version=14.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91. The dependencies are: System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089. You should either ensure that the dependent assembly is correct for the target framework, or ensure that the target framework you are addressing is that of the dependent assembly. 2>ASPNETCOMPILER(0,0): Warning : The following assembly has dependencies on a version of the .NET Framework that is higher than the target and might not load correctly during runtime causing a failure: Microsoft.Build.Tasks.Core, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a. The dependencies are: System.Security, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a; System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089. You should either ensure that the dependent assembly is correct for the target framework, or ensure that the target framework you are addressing is that of the dependent assembly.

I've tried to get rid of these warnings by adding assembly lines into the web.config's section but to no effect.

Chris C.
  • 908
  • 1
  • 10
  • 19
  • I don't think it's security issue. Try deleting all files & folders in publish folder and publish. – Prajwal Jan 19 '18 at 04:44
  • Tried that = no change - still get 404 when the VIews are compiled, works fine when they're not. – Chris C. Jan 19 '18 at 06:58
  • Check the .NET framework versions of both your local visual studio and wherever you are publishing it. They are different. I imagine it doesnt work because you are using a feature in your view using a higher version of .NET framework which you do not have installed on your target machine – Andrew Jan 19 '18 at 22:02
  • I'm publishing to a different folder on the same machine. I only get these warnings when I publish pre-compiling the Views. – Chris C. Jan 20 '18 at 02:30
  • Could you check the Windows system logs to see if there are any messages being logged there besides `HTTP Error 404.0 - Not Found` and if so, post them here? – NightOwl888 Jan 23 '18 at 06:59

2 Answers2

2

Best guess without seeing any of your .config or .csproj files is that you are missing the following section from your Web.config file:

<system.web>
  <compilation>
    <assemblies>
      <add assembly="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" />
    </assemblies>
  </compilation>
<system.web>

This only works if the referenced DLL is in the GAC. If it is not:

  1. Create a /Bin folder in your website root.
  2. Copy your DLL there.
  3. Do not add a reference in web.config.

References:

If That Doesn't Work

Visual Studio is a great tool. But it isn't so great at keeping dependencies in sync across a solution with multiple projects or even between project files and config files. Usually, when you need to upgrade or downgrade a dependency, something will inevitably end up being inconsistent between the main project's .csproj file and one or more dependent assembly .csproj files, or it may even be out of sync with .config files.

The only 100% reliable way to get past a scenario such as this is to manually review each dependency and ensure the version is consistent throughout all projects and config files.

Visual Studio 2017

Fortunately, in VS 2017 they made this easier to do. You can now simply right click the project and select Edit <projectName>.csproj.

Edit Project in Visual Studio 2017

Prior Versions of Visual Studio

  1. Right-click on your project node in Solution Explorer and click Unload Project.
  2. Right-click the project node again and click Edit <projectName>.csproj.

What to Look For

Here is an example of a MVC version mismatch that was resolved this way. It might help to create a fresh project from the MVC 5 template to see what an updated project is supposed to look like and then compare the differences between Web.config, Views/Web.config and .csproj files, and then cycle through each of the rest of the dependencies ensuring the version numbers are consistent and up-to-date.

Make sure to check if the .csproj files are using MSBuild conditions, as Visual Studio has no way to update these and they tend to be a major source of problems when it comes to upgrading.

Edit

In IIS I set up a Failed Request Trace and the first item created contained; ModuleName UrlAuthorization Notification AUTHORIZE_REQUEST HttpStatus 401 HttpReason Unauthorized etc...

The message indicates that your application is setup to use UrlAuthorization, and upon further research it appears it could either be configured as IIS URL Authorization or ASP.NET URL Authorization

If using ASP.NET URL Authorization, you will have a web.config entry like

<add name="UrlAuthorization" type="System.Web.Security.UrlAuthorizationModule" preCondition="managedHandler" />

If using IIS URL Authorization, you will have a web.config entry like

<add name="UrlAuthorizationModule" image="%windir%\System32\inetsrv\urlauthz.dll" />

I created a new MVC 5 project from the VS 2017 template (w/individual user accounts) and neither of these is typical of an MVC 5 application. I am not going to tell you that removing these is the solution, because there might be some valid reason why your application is using URL Authorization. It is apparently still the best way that an application can lock down files so they can't be served without logging in. Although, if it can be proven this is the root cause by removing the module you are using, then it will just be a matter of working out how to configure the URL Authorization module to work with MvcBuildViews enabled.

NightOwl888
  • 55,572
  • 24
  • 139
  • 212
  • The good news is: I broadly followed your advice and now the Publish with Pre-Compile doesn't kick out any warnings. :-) – Chris C. Jan 23 '18 at 06:37
  • The bad news is: I still get a 404 when starting the application using pre-compiled views & it's fine if the views aren't pre-compiled. Time to call it a day. – Chris C. Jan 23 '18 at 06:43
  • I was afraid that might happen. It may very well be that `MvcBuildViews` is not possible when you have a reference to `System.Windows.Forms` in the project. But as far as I can tell, that is a required dependency of SSRS. It might not hurt to try to remove the dependency on `Microsoft.ReportViewer.WinForms` to see if it will still build. – NightOwl888 Jan 23 '18 at 06:51
  • I removed the reference to System.Windows.Forms from the web.config and it still publishes with pre-compiled views without warnings or errors. But I still get a 404 error when trying to run with pre-compiled views. – Chris C. Jan 25 '18 at 02:53
  • In IIS I set up a Failed Request Trace and the first item created contained; ModuleName UrlAuthorization Notification AUTHORIZE_REQUEST HttpStatus 401 HttpReason Unauthorized etc... – Chris C. Jan 25 '18 at 03:01
  • Are you using the standard `IPrincipal/AuthorizeAttribute` setup with MS Membership, or have you customized it in some way? If the latter, could you please post the code? – NightOwl888 Jan 25 '18 at 08:44
  • I cannot find any reference to IPrincipal/AuthorizeAttribute in the code / classes. We're using the standard Membership class from System.Web.Security v4.0.0.0 - no amendments to the code but a few extra fields on the aspnet_* database tables. – Chris C. Jan 25 '18 at 09:16
  • See my edit. I think I found a clue in your previous comment, but you may need to play with the URL Authorization modules to see if that makes a difference. I would start off by removing them entirely (in a test environment if possible) and if that gets you by this error, then go back and try to find a way to reconfigure the URL Authorization to accept *whatever* is required by `MvcBuildViews` to make it work. – NightOwl888 Jan 25 '18 at 10:01
  • Cutting out the Membership code didn't make any difference. – Chris C. Jan 26 '18 at 06:40
2

Cutting out the Membership code and re-publishing didn't make any difference.

So I created a new MVC Project and roughly migrating the application's code into it. And it still publishes and runs compiled views !

So I know how to fix it, still don't know why but software's sometimes like that.

Thanks to all who tried to help esp. NightOwl888.

Chris C.
  • 908
  • 1
  • 10
  • 19