Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

update package failed to update binding redirects on a web application project #3298

Closed
jainaashish opened this issue Aug 10, 2016 · 13 comments
Assignees
Labels
Resolution:External This issue appears to be External to nuget

Comments

@jainaashish
Copy link

Repro steps:

  1. Create a new asp.net web application project
  2. build and run, it will run successfully.
  3. open PM UI and update newtonsoft.json package to latest
  4. Now build and run, it will show below error. And the root cause is after updating newtonsoft.json package, it doesn't update it's binding redirects in web.config.

Error:
Could not load file or assembly 'Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)

Expected:
It should successfully update binding redirects in web.config file and run successfully.

@rrelyea
Copy link
Contributor

rrelyea commented Aug 19, 2016

@jainaashish - can you please remind me which versions of NuGet have this problem?

@rrelyea rrelyea added the Viewed label Aug 19, 2016
@Mike-E-angelo
Copy link

I got the same problem with a non-web application project when updating Moq on all my testing projects recently. This worked flawlessly in 2.0 but not 3.0 it seems. Is this a supported feature?

@jainaashish
Copy link
Author

@rrelyea it's reproing with 3.4.4, 3.5.0-beta2, 3.5.0-rc1, and dev branch. I didn't try it with 3.4.3 or earlier builds.

@jainaashish jainaashish self-assigned this Aug 22, 2016
@jainaashish
Copy link
Author

@Mike-EEE Can you share a sample with your issue which involves non-web app projects? I looked deeper into my case and figured out for a web app project, there are multiple references for newtonsoft.json package in csproj file which causes this issue.

@Mike-E-angelo
Copy link

Well I wouldn't say sample, but I have a solution under heavy development that you can check out here:
https://github.com/DevelopersWin/VoteReporter/tree/development

I upgraded from NuGet 2.0 to 3.0, so I am no longer using any references under csproj's (that is, all references are in project.json now -- and work pretty well). Everything works like a champ with the exception of these assembly binding redirects. Moq recently upgraded its version and that is when I ran into this problem.

I have yet to hear from anyone whether this is expected to work in 3.0 as it did in 2.0, however. Sort of confusing and a bit frustrating at this point. 😛 FWIW, I started my inquiry on a recent NuGet blog post announcing 3.5 RC.

@jainaashish
Copy link
Author

As of now nuget doesn't handle binding redirects for project.json so it will need to be done manually. Work is in progress to get this feature well define and may gets into nuget 3.6

@Mike-E-angelo
Copy link

Great, thank you for the clarification, @jainaashish!

@Mike-E-angelo
Copy link

Just curious (said the cat 😸)... is this being tracked with an issue(s) here on GitHub by chance? Or perhaps we should create one?

@jainaashish
Copy link
Author

You can create one for this!

@Mike-E-angelo
Copy link

Great. Done:
#3372

(Thanks again to those who have put in the hard work and hours into 3.0!)

@jainaashish
Copy link
Author

Since this is not our issue, rather template system team and they are working on a fix. So closing this issue.

@jainaashish jainaashish added the Resolution:External This issue appears to be External to nuget label Aug 25, 2016
@rashadrivera
Copy link

I've developed a PowerShell script that will update your config file (be it web.config or app.config) based on the packages in your packages.config and the DLL(s) in your BIN directory; so I suggest you run it on a published product.

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' 'Web Configuration File|web.config|Application Configuration File|app.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

@rashadrivera
Copy link

BTW, the Add-BindingRedirect command of the NuGet package console does not work. It only updated 3 of the 72 referenced packages. The asterisks option did not help either (AKA "Add-BindingRedirect *")

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Resolution:External This issue appears to be External to nuget
Projects
None yet
Development

No branches or pull requests

4 participants