How to handle changeover from ASP MVC version 4.0.

2019-06-21 03:47发布

问题:

This is a followup to Windows update caused MVC3 and MVC4 stop working

I also had the issue where windows update on my development machine caused my MVC 4 project to stop working. I changed the assembly reference to target version 4.0.0.1 and it started working. For me.

My problem is that the application is then deployed on a number of web servers. Actually we have a build server where the customer versions are built and then a number of web servers.

First question: When we run windows update on the production servers are the old versions of the app going to stop working? I am guessing that the answer is "yes". We have not yet run windows update on either the build or production machines.

Changing the reference meant that it no longer could be built on the build machine. I can get around this by setting the Specific Version flag to false and Copy Local to true. Then it builds on both my development environment and on the build server.

Question: How lax is the check if I have Specific Version false? Does it allow 4.0.0.x? 4.0.x.x? 4.x.x.x? or x.x.x.x?

However, it even thoguh it builds in thsi configuration it then fails to run (cannot find assembly) on the test web server. The problem here is that I have the following in my web.config (as per Microsofts instructions when I upgraded from MVC 2 to MVC 4):

<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
  <dependentAssembly>
    <assemblyIdentity culture="neutral" name="System.Web.Mvc" publicKeyToken="31BF3856AD364E35"/>
    <bindingRedirect newVersion="4.0.0.1" oldVersion="0.0.0.0-4.0.0.1"/>
  </dependentAssembly>
  <dependentAssembly>
    <assemblyIdentity name="System.Web.Helpers" publicKeyToken="31bf3856ad364e35"/>
    <bindingRedirect newVersion="2.0.0.0" oldVersion="1.0.0.0"/>
  </dependentAssembly>
  <dependentAssembly>
    <assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35"/>
    <bindingRedirect newVersion="4.0.0.0" oldVersion="1.0.0.0-3.0.0.0"/>
  </dependentAssembly>
  <dependentAssembly>
    <assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35"/>
    <bindingRedirect newVersion="2.0.0.0" oldVersion="1.0.0.0"/>
  </dependentAssembly>
</assemblyBinding>

The problem is the line

<bindingRedirect newVersion="4.0.0.1" oldVersion="0.0.0.0-4.0.0.1"/>

for the System.Web.Mvc assembly. (It used to say 4.0.0.0 not 4.0.0.1 in that row of course.) If I change back to 4.0.0.0 on the test server then it works.

My problem is two-fold. Partly it is just that I want to be able to build and run both locally and on our build/production servers. However, we have a situation where we host a number of customers running different versions of our application on the same server. We cannot force all our customers to upgrade to latest version at once just because of this windows update fix - apart from anything else the web application is just part of a larger suite of applications so we would have to force them to upgrade the lot!

I suppose one option is to checkout each of the old version still in use, update the MVC version number and create a new version. Then when we update the web server we have to update all the customers on that server to a new (4.0.0.1 compatible) version of their current version. I'd really like to avoid having to update, commit and rebuild that many versions if possible.

Another option would be to not run the windows update on the web server and try and install both 4.0.0.0 and 4.0.0.1 dlls on the build machine. Then we could build both old and new version. Since any new versions (using 4.0.0.1) have CopyLocal set to true on the MVC assembly (the old ones do not) they should be able to be deployed to the web servers without the web servers themselves being updated.

Questions:

  • Does anyone know if it is possible to have both versions installed simultaneously? I am hoping I could simply save the 4.0.0.0 dll, run windows update then copy to old dll back to GAC alongside the new.
  • How serious is the security risk fixed by this patch? Is it a problem to allow people to run the old versions a while longer? Is just having the old .dll on the web server a security risk or only for the applications which use it?
  • Is there any way of doing a bindingRedirect to 4.0.0.x? or is it possible to simply remove the binding redirect altogether?

I cannot believe I am the only one in this situation and would also welcome any suggestions for solutions I haven't thought of at all.

回答1:

I was a member of a team that encountered this same problem from a slightly different angle. The error message that it posts when the security update is wrong can be misleading and hard to interpret. We ran into deployment and build errors when we tried to publish our apps to different environments. The root cause was that this patch was applied via windows update on some test environments but not on other servers. Any server that did not have the patch would crash when we deployed our application. I would recommend having your systems team apply the patch and upgrade all of your applications to reference this DLL. Security updates Because the library referenced is ignored in source control, but still spelled out verbosely in web configs it needs to be addressed quickly. Some environments will allow you to right click and choose which MVC dll version to use locally and still deploy your application without issues. If you are using web deploy, and MUST have the ability to switch, you could write web config transforms for each Transforms web config. One thing i noticed when fixing this issue (upgrading to 4.0.0.1) is that upgrading to the latest version of MVC.dll in my project allowed me to get the latest versions of nuget packages. If you do not upgrade and stay with the old versions, you will be stuck with old versions of the MVC javascript, jquery, and other libraries.