msbuild: PackageReference is not resolved while it works in Visual Studio
Steps to reproduce
- Create a Empty Web Application Project in Visual Studio.
- Make it really empty by removing the DotNetCompilerPlatform stuff
- Add a Nuget package reference to
Microsoft.AspNet.Mvc
version 5.2.4 - Add a Global.asax and its code behind with a
using System.Web.Mvc
- Compile in Visual Studio
- Compile from the command line
Directory contents:
/
- Properties/
- AssemblyInfo.cs
- Global.asax
- Global.asax.cs
- web.config
- Empty.WebHost.csproj
Empty.WebHost.csproj:
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>
</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{080CBD85-3B74-4ECC-8389-47E594F376DE}</ProjectGuid>
<ProjectTypeGuids>{349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuids>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Empty.WebHost</RootNamespace>
<AssemblyName>Empty.WebHost</AssemblyName>
<TargetFrameworkVersion>v4.6.2</TargetFrameworkVersion>
<UseIISExpress>true</UseIISExpress>
<Use64BitIISExpress />
<IISExpressSSLPort />
<IISExpressAnonymousAuthentication />
<IISExpressWindowsAuthentication />
<IISExpressUseClassicPipelineMode />
<UseGlobalApplicationHostFile />
<NuGetPackageImportStamp>
</NuGetPackageImportStamp>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Web.DynamicData" />
<Reference Include="System.Web.Entity" />
<Reference Include="System.Web.ApplicationServices" />
<Reference Include="System.ComponentModel.DataAnnotations" />
<Reference Include="System" />
<Reference Include="System.Data" />
<Reference Include="System.Core" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="System.Web.Extensions" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Drawing" />
<Reference Include="System.Web" />
<Reference Include="System.Xml" />
<Reference Include="System.Configuration" />
<Reference Include="System.Web.Services" />
<Reference Include="System.EnterpriseServices" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNet.Mvc" Version="5.2.4" />
</ItemGroup>
<ItemGroup>
<Content Include="Web.config" />
<Content Include="Global.asax" />
</ItemGroup>
<ItemGroup>
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Global.asax.cs">
<DependentUpon>Global.asax</DependentUpon>
</Compile>
</ItemGroup>
<PropertyGroup>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">15.0</VisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
</PropertyGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<Import Project="$(VSToolsPath)\WebApplications\Microsoft.WebApplication.targets" Condition="'$(VSToolsPath)' != ''" />
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" Condition="false" />
<ProjectExtensions>
<VisualStudio>
<FlavorProperties GUID="{349c5851-65df-11da-9384-00065b846f21}">
<WebProjectProperties>
<UseIIS>True</UseIIS>
<AutoAssignPort>True</AutoAssignPort>
<DevelopmentServerPort>1983</DevelopmentServerPort>
<DevelopmentServerVPath>/</DevelopmentServerVPath>
<IISUrl>http://localhost:1983/</IISUrl>
<NTLMAuthentication>False</NTLMAuthentication>
<UseCustomServer>False</UseCustomServer>
<CustomServerUrl>
</CustomServerUrl>
<SaveServerSettingsInUserFile>False</SaveServerSettingsInUserFile>
</WebProjectProperties>
</FlavorProperties>
</VisualStudio>
</ProjectExtensions>
</Project>
Global.asax:
<%@ Application Codebehind="Global.asax.cs" Inherits="Empty.Web" Language="C#" %>
Global.asax.cs:
using System.Web;
using System.Web.Mvc;
namespace Empty.Web
{
public class MvcApplication : HttpApplication
{
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
}
}
}
web.config:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
</configuration>
Properties\AssemblyInfo.cs:
using System.Reflection;
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
Command line
msbuild .\Empty.WebHost.csproj /t:restore,Build
Expected behavior
The build should succeed in Visual Studio. The build should succeed on the command line.
Actual behavior
The build succeeds in Visual Studio. The build fails on the command line.
Build FAILED.
"P:\cy\apps\cam\src\Core\Empty.WebHost\Empty.WebHost.csproj" (restore;Build target) (1) ->
(CoreCompile target) ->
Global.asax.cs(2,18): error CS0234: The type or namespace name 'Mvc' does not exist in the namespace 'System.Web' (are you missing an assembly reference?) [ P:\cy\apps\cam\src\Core\Empty.WebHost\Empty.WebHost.csproj]
0 Warning(s)
1 Error(s)
Environment data
msbuild /version
output:
Microsoft (R) Build Engine version 15.5.180.51428 for .NET Framework
Copyright (C) Microsoft Corporation. All rights reserved.
15.5.180.51428
OS info: Windows 10 Visual Studio 2017 15.5.6
About this issue
- Original URL
- State: closed
- Created 6 years ago
- Comments: 19 (6 by maintainers)
Commits related to this issue
- Bump to xamarin/Java.Interop/master@56c92c70 (#4376) Changes: https://github.com/xamarin/Java.Interop/compare/1a086ffd51436ec3bb78467a150e4f9121d57419...56c92c70887c58275917752450126c8c39988aa2 ... — committed to xamarin/xamarin-android by jonpryor 4 years ago
- [build] /restore no longer needed on Windows On macOS, you can generally build with just: make prepare all On Windows: msbuild Xamarin.Android.sln /t:Prepare msbuild Xamarin.Android.s... — committed to jonathanpeppers/xamarin-android by jonathanpeppers 4 years ago
/t:Restore;Build
does not work reliably. Instead, specifymsbuild.exe /restore
, which runs the restore operation in a separate phase and ensures that the build operates with the latest restored build logic.Adding a separate project that uses
<MSBuild
withTargets="Restore;Build"
will also not be reliable.Running
nuget.exe
within MSBuild also will not work.The core problems with all of these approaches are the same: MSBuild tries very hard to avoid loading projects more than it needs to. That means that if you modify the project (or create new imports, such as by restoring NuGet packages) after the project has already started building, the rest of that build will not see the updated build logic, because it’s already read from disk.
The
/restore
command-line argument fixes this by doing the/t:Restore
in a separate phase, allowing the rest of the build (as specified on the command line) to pick up the latest logic.In my case the root cause of this issue was old Nuget.exe version. Old version used old MsBuild v14 instead on v15 and it causes build issues after nuget restore. Try to update it with
nuget.exe update -self
Or try to change
ToolsVersion="12.0"
toToolsVersion="15.0"
in csproj filesThat’s tracked by #2811, but to set expectations it’s definitely very hard and possibly too hard, which is why it isn’t done already.
Is it possible for you to have a
Restore
target in the file that definesBuildTIMSNET
that does something like?
Also,
msbuild.exe /restore
runs Restore and then the default target. If you want to do the exec-MSBuild approach for a subtree, you should callmsbuild.exe /t:Restore
to run just the restore operation and do the build with the MSBuild task.