7

Ich habe ein internes NuGet-Paket, das eine einzelne DLL, keine externen NuGet-Paketabhängigkeiten und keine web.config-Transformationen enthält.Nuget Update-Paket aktualisiert die Assembly-Binding-Weiterleitungen falsch

Doch wenn ich ein Update-Paket auf meine Projekte (Klasse lib und Website) für diese spezifische NuGet laufen, wird es automatisch meine Website web.config Montage Bindung Umleitungen zu ältere Versionen von System.Web.Mvc und Newtonsoft aktualisiert .Json. Auf der Website web.config sind sie aktuell an die aktuellste Version gebunden.

Mit der GUI, mit NuGet-Pakete verwalten für Lösung ... Ich möchte dieses NuGet für anwendbare Projekte aktualisieren, die einen Verweis auf die alte Version haben. Aktualisieren Sie dann wählen

Hier die Ausgabe von Package Manager ist: http://pastebin.com/3ySwTRFR

Und mein web.config aus ging:

<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> 

An:

<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> 

The NuGet Paket Ich bin Aktualisierung hat eine DLL, die Newtonsoft.Json verweist (aber nicht explizit eine NuGet-Paketabhängigkeit)

Wenn ein unwissender Entwickler dieses NuGet-Paket aktualisiert, unterbricht es die Laufzeit, indem es nach einer alten Version von MVC- oder JSON.NET-DLLs sucht. In der Vergangenheit habe ich versucht, -IgnoreDependencies powershell command switch zu verwenden, aber dies scheint keine Auswirkungen auf das Problem zu haben.

Irgendeine Idee, was könnte meine web.configs (ohne eine explizite Transformation) während Update-Paket transformieren?

Edit: VS2015 w/NuGet 3.3.0 scheint sich besser zu benehmen ... beim zufälligen Paketupdate fand es eine alte BAD Binding Redirect und korrigierte es! enter image description here

Antwort

7

überspringen Bindung Umleitungen Anwendung ist eine Option jetzt in NuGet 3.3.0: Issue #1147

enter image description here

0

ich eine bessere Lösung haben. Da ich absolut verrückt bin, wenn ich jedes Mal, wenn ich meine Pakete aktualisiere, über 72 Referenzen aktualisieren muss, habe ich ein PowerShell-Skript entwickelt, das Ihre Web.Config basierend auf den Paketen in Ihrer packages.config und den von Ihnen im BIN veröffentlichten DLLs aktualisiert Verzeichnis.

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 
+0

BTW, das Add-BindingRedicrect-Paket Konsolenbefehl funktioniert nicht. Es aktualisiert nur 3 von 72 referenzierten Paketen. Das Skript, das ich zur Verfügung gestellt habe, durchläuft alle von ihnen und handelt auf alle Pacakges in der "packages.config", es sei denn, die DLL existiert im BIN-Verzeichnis. – RashadRivera