【问题标题】:Nuget Update-Package incorrectly updating assembly binding redirectsNuget Update-Package 错误地更新程序集绑定重定向
【发布时间】:2019-03-27 19:13:23
【问题描述】:

我有一个包含单个 dll 的内部 NuGet 包,没有外部 NuGet 包依赖项,也没有 web.config 转换。

然而,当我在我的项目(类库和网站)上为此特定 NuGet 运行 Update-Package 时,它​​会自动更新我的网站 web.config 程序集绑定重定向到 版本的 System.Web .Mvc 和 Newtonsoft.Json。网站 web.config 当前将它们绑定到正在使用的最新版本。

使用 GUI,利用管理 NuGet 包进行解决方案...我选择为引用旧版本的适用项目更新此 NuGet。然后选择更新

这是包管理器的输出:http://pastebin.com/3ySwTRFR

我的 web.config 来自:

  <dependentAssembly>
    <assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
    <bindingRedirect oldVersion="0.0.0.0-5.1.0.0" newVersion="5.1.0.0" />
  </dependentAssembly>

  <dependentAssembly>
    <assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
    <bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
  </dependentAssembly>

收件人:

  <dependentAssembly>
    <assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
    <bindingRedirect oldVersion="0.0.0.0-4.0.0.1" newVersion="4.0.0.1" />
  </dependentAssembly>

  <dependentAssembly>
    <assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
    <bindingRedirect oldVersion="0.0.0.0-4.5.0.0" newVersion="4.5.0.0" />
  </dependentAssembly>

我正在更新的 NuGet 包有一个引用 Newtonsoft.Json 的 dll(但没有明确地成为 NuGet 包依赖项)

当不知情的开发人员更新此 NuGet 包时,它会中断运行时以查找旧版本的 MVC 或 JSON.NET dll。

过去我曾尝试使用-IgnoreDependencies powershell command switch,但这似乎对问题没有影响。

关于在更新包期间什么可以转换我的 web.configs(没有显式转换)的任何想法?

编辑:带有 NuGet 3.3.0 的 VS2015 似乎表现更好......在随机包更新期间,它发现了一个旧的 BAD 绑定重定向并更正了它!

【问题讨论】:

    标签: asp.net-mvc visual-studio-2013 json.net nuget assembly-binding-redirect


    【解决方案1】:

    现在在 NuGet 3.3.0 中跳过应用绑定重定向是一个选项:Issue #1147

    【讨论】:

      【解决方案2】:

      在包管理器控制台中使用以下命令

      PM> 获取项目 – 全部 |添加绑定重定向

      详细解释请参考https://weblog.west-wind.com/posts/2014/nov/29/updating-assembly-redirects-with-nuget

      【讨论】:

      • 太棒了!不知道这个 CMD - 虽然我的问题是 NuGet 首先弄乱了工作目录,所以只是不应用它们对我有用。
      • 当我运行它时,NuGet 继续使用旧版本的包(在我的例子中是Microsoft.IdentityModel.Tokens)。我所有的项目都引用了5.6.0,但它不断向5.5.0 添加绑定重定向。 Grrrr。
      【解决方案3】:

      我有一个更好的解决方案。因为每次更新我的包时必须更新超过 72 个引用时我会变得非常疯狂,所以我开发了一个 PowerShell 脚本,它根据你的 packages.config 中的包和你在 BIN 中发布的 DLL 更新你的 Web.Config目录。

      param (
          [Parameter(Mandatory=$false)]
          [string] $webConfigPath,
          [string] $packagesConfigPath,
          [string] $binPath
      )
      
      [bool]$isWindowsFormsAssemblyLoaded = $false
      [System.Xml.Linq.XNamespace]$ns1 = "urn:schemas-microsoft-com:asm.v1"
      
      function ClearBindings([System.Xml.Linq.XDocument] $xml) {
      
          $elements = $xml.Root.Element("runtime").Element($ns1 + "assemblyBinding").Elements()
          $l1 = New-Object "System.Collections.Generic.List[System.Xml.Linq.XElement]"
          $l1.AddRange($elements)
      
          $l1 | ForEach-Object { $_.Remove() }
      }
      function GetPackageList([System.Xml.Linq.XDocument] $xml, [string] $binPath) {
      
          $elements = $xml.Root.Elements("package")
          $l1 = New-Object "System.Collections.Generic.List[System.Xml.Linq.XElement]"
          $l1.AddRange($elements)
      
          [System.Collections.Generic.List[string]]$packageList = New-Object "System.Collections.Generic.List[string]"
          $l1 | ForEach-Object { $packageList.Add("$binPath\" + $_.Attribute("id").Value + ".dll") }
          return $packageList
      }
      function ExtractPublicKey([System.Reflection.Assembly]$asm) {
          $bytes = $asm.GetName().GetPublicKeyToken()
          return [System.BitConverter]::ToString($bytes).Replace("-", "")
      }
      function ExtractCulterInfoName($asm) {
          if ($asm.GetName().CultureInfo.TextInfo.CultureName -eq "") {
              return "neutral"
          } else {
              return $asm.GetName().CultureInfo.TextInfo.CultureName
          }
      }
      function CreateBindingElement([System.IO.FileInfo] $fi) {
      
          [System.Reflection.Assembly]$asm = [System.Reflection.Assembly]::LoadFile($fi.FullName)
          $publicKey = ExtractPublicKey $asm
          $culterInfo = ExtractCulterInfoName $asm
      
          $assemblyIdentity = [System.Xml.Linq.XElement]::new($ns1 + "assemblyIdentity")
          $assemblyIdentity.Add([System.Xml.Linq.XAttribute]::new("name", $asm.GetName().Name))
          $assemblyIdentity.Add([System.Xml.Linq.XAttribute]::new("publicKeyToken", $publicKey))
          $assemblyIdentity.Add([System.Xml.Linq.XAttribute]::new("culture", $culterInfo))
      
          $bindingRedirect = [System.Xml.Linq.XElement]::new($ns1 + "bindingRedirect")
          $bindingRedirect.Add([System.Xml.Linq.XAttribute]::new("oldVersion", "0.0.0.0-65535.65535.65535.65535"))
          $bindingRedirect.Add([System.Xml.Linq.XAttribute]::new("newVersion", $asm.GetName().Version<#$fi.VersionInfo.FileVersion#>))
      
          return [System.Xml.Linq.XElement]::new($ns1 + "dependentAssembly", $assemblyIdentity, $bindingRedirect)
      }
      function UpdateBindings([string] $webConfigPath, [string] $packageConfigPath, [string] $binPath) {
      
          $webConfig = [System.Xml.Linq.XDocument]::Load($webConfigPath)
          ClearBindings $webConfig
      
          [System.Xml.Linq.XDocument] $packageConfig = [System.Xml.Linq.XDocument]::Load($packageConfigPath)
          $packages = GetPackageList $packageConfig $binPath
      
          [System.Xml.Linq.XElement]$assemblyBinding = $webConfig.Root.Element("runtime").Element($ns1 + "assemblyBinding")
      
          $packages | ForEach-Object {
      
              [System.IO.FileInfo]$fi = [System.IO.FileInfo]::new($_)
              if ($fi.Exists) {
                  $newElement = CreateBindingElement $fi
                  $assemblyBinding.Add($newElement)
              }
          }
      
          $webConfig.Save($webConfigPath)
      }
      function LoadWindowsFormsAssembly() {
          if (!$isWindowsFormsAssemblyLoaded) {
              [void][System.Reflection.Assembly]::LoadWithPartialName('System.Windows.Forms')
              $isWindowsFormsAssemblyLoaded = $true
          }
      }
      function PromptForFile ([string]$title, [string]$filter) {
      
          LoadWindowsFormsAssembly
          [System.Windows.Forms.OpenFileDialog]$dialog = New-Object System.Windows.Forms.OpenFileDialog
          $dialog.Multiselect = $false
          $dialog.Title = $title
          $dialog.Filter = $filter
      
          if ($dialog.ShowDialog() -eq [System.Windows.Forms.DialogResult]::OK) { return $dialog.FileName }
          else { return $null }
      }
      function PromptForDirectory ([string]$title) {
      
          LoadWindowsFormsAssembly
          [System.Windows.Forms.FolderBrowserDialog]$dialog = New-Object System.Windows.Forms.FolderBrowserDialog
      
          if ($dialog.ShowDialog() -eq [System.Windows.Forms.DialogResult]::OK) { return $dialog.SelectedPath }
          else { return $null }
      }
      function MessageBox([string]$title) {
      
          LoadWindowsFormsAssembly
          [System.Windows.Forms.MessageBox]::Show($title)
      }
      
      if ([System.String]::IsNullOrEmpty($webConfigPath)) {
          $webConfigPath = PromptForFile 'Please select the web.config file' '.NET Configuration File (web.config)|web.config'
          if ([System.String]::IsNullOrEmpty($webConfigPath)) {exit}
      }
      
      if ([System.String]::IsNullOrEmpty($packagesConfigPath)) {
          $packagesConfigPath = PromptForFile 'Please select the packages.config file' 'NuGet Package  File (packages.config)|packages.config'
          if ([System.String]::IsNullOrEmpty($packagesConfigPath)) {exit}
      }
      
      if ([System.String]::IsNullOrEmpty($binPath)) {
          $binPath = PromptForDirectory "Please select your application's BIN directory"
          if ([System.String]::IsNullOrEmpty($binPath)) {exit}
      }
      
      
      UpdateBindings $webConfigPath $packagesConfigPath $binPath
      

      【讨论】:

      • 顺便说一句,Add-BindingRedicrect 包控制台命令不起作用。它仅更新 72 个引用包中的 3 个。我提供的脚本会遍历所有这些并作用于“packages.config”中的任何包,除非 BIN 目录中存在 DLL。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-04-27
      • 2017-02-16
      • 2019-12-21
      • 1970-01-01
      • 2021-07-16
      • 2021-10-01
      • 2021-10-18
      相关资源
      最近更新 更多