Skip to content
This repository was archived by the owner on May 17, 2024. It is now read-only.

Commit 3b45e40

Browse files
authored
Merge pull request #387 from mjrousos/mjrousos/web-libraries
2 parents cf413c5 + 3dd3caf commit 3b45e40

File tree

17 files changed

+338
-22
lines changed

17 files changed

+338
-22
lines changed

src/MSBuild.Abstractions/MSBuildConversionWorkspace.cs

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,13 @@ private bool TryCreateSdkBaselineProject(string projectFilePath, IProject projec
142142
: DesktopFacts.WinSDKAttribute; // pre-.NET 5 apps need a special SDK attribute.
143143
break;
144144
case ProjectStyle.Web:
145-
rootElement.Sdk = WebFacts.WebSDKAttribute;
145+
rootElement.Sdk =
146+
// Web apps should use the web SDK (there's no good way to build a classic web apps with SDK-style projects)
147+
// but libraries with web dependencies should only use the web SDK if the TFM is updating. Otherwise, they
148+
// can work as classic ASP.NET libraries.
149+
MSBuildHelpers.IsAspNetCore(root, keepCurrentTFMs ? project.GetTargetFramework() : tfm)
150+
? WebFacts.WebSDKAttribute
151+
: MSBuildFacts.DefaultSDKAttribute;
146152
break;
147153
default:
148154
baselineProject = null;
@@ -231,10 +237,10 @@ private ProjectOutputType GetProjectOutputType(IProjectRootElement root) =>
231237

232238
private ProjectOutputType GetProjectOutputType(IProjectRootElement root, ProjectStyle projectStyle)
233239
{
234-
if (projectStyle == ProjectStyle.Web)
240+
if (MSBuildHelpers.IsWebApp(root))
235241
{
236242
// ASP.NET Core apps use an EXE output type even though legacy ASP.NET apps use Library
237-
// Note that this specifically checks the project style only (rather than a System.Web reference) since
243+
// Note that this specifically checks the project guid type only (rather than a System.Web reference) since
238244
// ASP.NET libraries may reference System.Web and should still use a Library output types. Only ASP.NET
239245
// apps should convert with Exe output type.
240246
return ProjectOutputType.Exe;
@@ -329,7 +335,7 @@ private bool IsSupportedProjectType(IProjectRootElement root, bool forceWeb)
329335
switch (projectType)
330336
{
331337
case ProjectSupportType.LegacyWeb:
332-
Console.WriteLine($"'{root.FullPath}' is a legacy web project and/or reference System.Web. Legacy Web projects and System.Web are unsupported on .NET Core. You will need to rewrite your application or find a way to not depend on System.Web to convert this project.");
338+
Console.WriteLine($"'{root.FullPath}' is a legacy web project and/or references System.Web. Legacy Web projects and System.Web are unsupported on .NET Core. You will need to rewrite your application or find a way to not depend on System.Web to convert this project.");
333339

334340
// Proceed only if migrating web scenarios is explicitly enabled
335341
return forceWeb;

src/MSBuild.Abstractions/MSBuildHelpers.cs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,21 @@ public static bool IsWeb(IProjectRootElement projectRoot)
228228
}
229229
}
230230

231+
/// <summary>
232+
/// Determines if a given project uses ASP.NET web app project type guid
233+
/// </summary>
234+
public static bool IsWebApp(IProjectRootElement projectRoot) =>
235+
projectRoot.PropertyGroups.Any(pg => pg.Properties.Any(ProjectPropertyHelpers.IsLegacyWebProjectTypeGuidsProperty));
236+
237+
/// <summary>
238+
/// Determines if a project should be treated as an ASP.NET Core project (as opposed to classic ASP.NET). Returns
239+
/// true if the project is a web app (since there's no good way to build an ASP.NET app with an SDK-style project
240+
/// except to upgrade to ASP.NET Core) or the project has web dependencies and will target .NET/.NET Core.
241+
/// </summary>
242+
public static bool IsAspNetCore(IProjectRootElement projectRoot, string tfm) =>
243+
IsWebApp(projectRoot) || projectRoot.Sdk.Equals(WebFacts.WebSDKAttribute)
244+
|| (IsWeb(projectRoot) && new[] { MSBuildFacts.Net5, MSBuildFacts.NetcoreappPrelude }.Any(s => tfm.StartsWith(s, StringComparison.OrdinalIgnoreCase)));
245+
231246
/// <summary>
232247
/// Determines if a project is a .NET Framework MSTest project by looking at its references.
233248
/// </summary>

src/MSBuild.Abstractions/ProjectPropertyHelpers.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ public static bool IsProjectTypeGuidsNode(ProjectPropertyElement prop) =>
9797
/// Determines if a property lists the default project type GUIds for legacy web projects.
9898
/// </summary>
9999
public static bool IsLegacyWebProjectTypeGuidsProperty(ProjectPropertyElement prop) =>
100-
IsProjectTypeGuidsNode(prop) && prop.Value.Split(';').Any(guidString => MSBuildFacts.LegacyWebProjectTypeGuids.Contains(Guid.Parse(guidString)));
100+
IsProjectTypeGuidsNode(prop) && prop.Value.Split(';').Any(guidString => WebFacts.LegacyWebProjectTypeGuids.Contains(Guid.Parse(guidString)));
101101

102102
/// <summary>
103103
/// Checks if a given OutputType node is wither a library, exe, or WinExe.

src/MSBuild.Conversion.Facts/MSBuildFacts.cs

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -146,9 +146,11 @@ public static class MSBuildFacts
146146
"System.EnterpriseServices",
147147

148148
// System.Net.Http is a part of the .NET SDK now
149-
"System.Net.Http",
149+
"System.Net.Http"
150+
);
150151

151-
// ASP.NET references are no longer used
152+
public static ImmutableArray<string> UnnecessaryWebIncludes => ImmutableArray.Create(
153+
// ASP.NET references are no longer used by web apps
152154
"System.Web",
153155
"System.Web.Abstractions",
154156
"System.Web.ApplicationServices",
@@ -244,15 +246,6 @@ public static class MSBuildFacts
244246
"ProjectReference"
245247
);
246248

247-
public static ImmutableArray<Guid> LegacyWebProjectTypeGuids => ImmutableArray.Create(
248-
Guid.Parse("{349c5851-65df-11da-9384-00065b846f21}"), // ASP.NET MVC 5
249-
Guid.Parse("{E3E379DF-F4C6-4180-9B81-6769533ABE47}"), // ASP.NET MVC 4
250-
Guid.Parse("{E53F8FEA-EAE0-44A6-8774-FFD645390401}"), // ASP.NET MVC 3
251-
Guid.Parse("{F85E285D-A4E0-4152-9332-AB1D724D3325}"), // ASP.NET MVC 2
252-
Guid.Parse("{603C0E0B-DB56-11DC-BE95-000D561079B0}"), // ASP.NET MVC 1
253-
Guid.Parse("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") // ASP.NET 5
254-
);
255-
256249
public static ImmutableArray<Guid> LanguageProjectTypeGuids => ImmutableArray.Create(
257250
Guid.Parse("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}"), // C#
258251
Guid.Parse("{F2A71F9B-5D33-465A-A702-920D77279786}"), // VB.NET

src/MSBuild.Conversion.Facts/WebFacts.cs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using System.Collections.Immutable;
1+
using System;
2+
using System.Collections.Immutable;
23

34
namespace MSBuild.Conversion.Facts
45
{
@@ -9,6 +10,15 @@ public static class WebFacts
910
public const string WebProjectPropertiesName = "WebProjectProperties";
1011
public const string WebApplicationTargets = "Microsoft.WebApplication.targets";
1112

13+
public static ImmutableArray<Guid> LegacyWebProjectTypeGuids => ImmutableArray.Create(
14+
Guid.Parse("{349c5851-65df-11da-9384-00065b846f21}"), // ASP.NET MVC 5
15+
Guid.Parse("{E3E379DF-F4C6-4180-9B81-6769533ABE47}"), // ASP.NET MVC 4
16+
Guid.Parse("{E53F8FEA-EAE0-44A6-8774-FFD645390401}"), // ASP.NET MVC 3
17+
Guid.Parse("{F85E285D-A4E0-4152-9332-AB1D724D3325}"), // ASP.NET MVC 2
18+
Guid.Parse("{603C0E0B-DB56-11DC-BE95-000D561079B0}"), // ASP.NET MVC 1
19+
Guid.Parse("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") // ASP.NET 5
20+
);
21+
1222
/// <summary>
1323
/// The core set of references all ASP.NET projects use.
1424
/// </summary>

src/MSBuild.Conversion.Project/ProjectRootElementExtensionsForConversion.cs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,10 @@ public static IProjectRootElement ChangeImportsAndAddSdkAttribute(this IProjectR
3232
{
3333
projectRootElement.Sdk = DesktopFacts.WinSDKAttribute;
3434
}
35-
else if (MSBuildHelpers.IsWeb(projectRootElement))
35+
else if (MSBuildHelpers.IsAspNetCore(projectRootElement, baselineProject.TargetTFM))
3636
{
37+
// Libraries targeting .NET Framework can use the default SDK and still be used by NetFx callers.
38+
// However, web apps (as opposed to libraries) or libraries that are targeting .NET Core/.NET should use the web SDK.
3739
projectRootElement.Sdk = WebFacts.WebSDKAttribute;
3840
}
3941
else
@@ -174,6 +176,10 @@ public static IProjectRootElement RemoveOrUpdateItems(this IProjectRootElement p
174176
{
175177
itemGroup.RemoveChild(item);
176178
}
179+
else if (MSBuildFacts.UnnecessaryWebIncludes.Contains(item.Include, StringComparer.OrdinalIgnoreCase) && MSBuildHelpers.IsAspNetCore(projectRootElement, tfm))
180+
{
181+
itemGroup.RemoveChild(item);
182+
}
177183
else if (ProjectItemHelpers.IsExplicitValueTupleReferenceThatCanBeRemoved(item, tfm))
178184
{
179185
itemGroup.RemoveChild(item);
@@ -365,6 +371,12 @@ public static IProjectRootElement ConvertAndAddPackages(this IProjectRootElement
365371
continue;
366372
}
367373

374+
if (MSBuildFacts.UnnecessaryWebIncludes.Contains(pkgref.ID, StringComparer.OrdinalIgnoreCase)
375+
&& MSBuildHelpers.IsAspNetCore(projectRootElement, tfm))
376+
{
377+
continue;
378+
}
379+
368380
AddPackageReferenceElement(groupForPackageRefs, pkgref.ID, pkgref.Version);
369381
}
370382

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
using System.Reflection;
2+
using System.Runtime.CompilerServices;
3+
using System.Runtime.InteropServices;
4+
5+
// General Information about an assembly is controlled through the following
6+
// set of attributes. Change these attribute values to modify the information
7+
// associated with an assembly.
8+
[assembly: AssemblyTitle("Helper")]
9+
[assembly: AssemblyDescription("")]
10+
[assembly: AssemblyConfiguration("")]
11+
[assembly: AssemblyCompany("")]
12+
[assembly: AssemblyProduct("Helper")]
13+
[assembly: AssemblyCopyright("Copyright © 2021")]
14+
[assembly: AssemblyTrademark("")]
15+
[assembly: AssemblyCulture("")]
16+
17+
// Setting ComVisible to false makes the types in this assembly not visible
18+
// to COM components. If you need to access a type in this assembly from
19+
// COM, set the ComVisible attribute to true on that type.
20+
[assembly: ComVisible(false)]
21+
22+
// The following GUID is for the ID of the typelib if this project is exposed to COM
23+
[assembly: Guid("9be957f4-d033-4dd4-83cc-77fb64ab3020")]
24+
25+
// Version information for an assembly consists of the following four values:
26+
//
27+
// Major Version
28+
// Minor Version
29+
// Build Number
30+
// Revision
31+
//
32+
// You can specify all the values or you can default the Build and Revision Numbers
33+
// by using the '*' as shown below:
34+
// [assembly: AssemblyVersion("1.0.*")]
35+
[assembly: AssemblyVersion("1.0.0.0")]
36+
[assembly: AssemblyFileVersion("1.0.0.0")]
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
3+
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
4+
<PropertyGroup>
5+
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
6+
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
7+
<ProjectGuid>{9BE957F4-D033-4DD4-83CC-77FB64AB3020}</ProjectGuid>
8+
<OutputType>Library</OutputType>
9+
<AppDesignerFolder>Properties</AppDesignerFolder>
10+
<RootNamespace>SmokeTests.LegacyWebLibrary</RootNamespace>
11+
<AssemblyName>SmokeTests.LegacyWebLibrary</AssemblyName>
12+
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
13+
<FileAlignment>512</FileAlignment>
14+
<Deterministic>true</Deterministic>
15+
</PropertyGroup>
16+
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
17+
<DebugSymbols>true</DebugSymbols>
18+
<DebugType>full</DebugType>
19+
<Optimize>false</Optimize>
20+
<OutputPath>bin\Debug\</OutputPath>
21+
<DefineConstants>DEBUG;TRACE</DefineConstants>
22+
<ErrorReport>prompt</ErrorReport>
23+
<WarningLevel>4</WarningLevel>
24+
</PropertyGroup>
25+
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
26+
<DebugType>pdbonly</DebugType>
27+
<Optimize>true</Optimize>
28+
<OutputPath>bin\Release\</OutputPath>
29+
<DefineConstants>TRACE</DefineConstants>
30+
<ErrorReport>prompt</ErrorReport>
31+
<WarningLevel>4</WarningLevel>
32+
</PropertyGroup>
33+
<ItemGroup>
34+
<Reference Include="Microsoft.Web.Infrastructure, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
35+
<HintPath>..\packages\Microsoft.Web.Infrastructure.1.0.0.0\lib\net40\Microsoft.Web.Infrastructure.dll</HintPath>
36+
</Reference>
37+
<Reference Include="Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
38+
<HintPath>..\packages\Newtonsoft.Json.6.0.5\lib\net45\Newtonsoft.Json.dll</HintPath>
39+
</Reference>
40+
<Reference Include="System" />
41+
<Reference Include="System.Core" />
42+
<Reference Include="System.Web" />
43+
<Reference Include="System.Web.Helpers, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
44+
<HintPath>..\packages\Microsoft.AspNet.WebPages.3.2.7\lib\net45\System.Web.Helpers.dll</HintPath>
45+
</Reference>
46+
<Reference Include="System.Web.Mvc, Version=5.2.7.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
47+
<HintPath>..\packages\Microsoft.AspNet.Mvc.5.2.7\lib\net45\System.Web.Mvc.dll</HintPath>
48+
</Reference>
49+
<Reference Include="System.Web.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
50+
<HintPath>..\packages\Microsoft.AspNet.Razor.3.2.7\lib\net45\System.Web.Razor.dll</HintPath>
51+
</Reference>
52+
<Reference Include="System.Web.WebPages, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
53+
<HintPath>..\packages\Microsoft.AspNet.WebPages.3.2.7\lib\net45\System.Web.WebPages.dll</HintPath>
54+
</Reference>
55+
<Reference Include="System.Web.WebPages.Deployment, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
56+
<HintPath>..\packages\Microsoft.AspNet.WebPages.3.2.7\lib\net45\System.Web.WebPages.Deployment.dll</HintPath>
57+
</Reference>
58+
<Reference Include="System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
59+
<HintPath>..\packages\Microsoft.AspNet.WebPages.3.2.7\lib\net45\System.Web.WebPages.Razor.dll</HintPath>
60+
</Reference>
61+
<Reference Include="System.Xml.Linq" />
62+
<Reference Include="System.Data.DataSetExtensions" />
63+
<Reference Include="Microsoft.CSharp" />
64+
<Reference Include="System.Data" />
65+
<Reference Include="System.Net.Http" />
66+
<Reference Include="System.Xml" />
67+
</ItemGroup>
68+
<ItemGroup>
69+
<Compile Include="WebHelpers.cs" />
70+
<Compile Include="Properties\AssemblyInfo.cs" />
71+
</ItemGroup>
72+
<ItemGroup>
73+
<None Include="packages.config" />
74+
</ItemGroup>
75+
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
76+
</Project>
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
using System.Web;
2+
using System.Web.Mvc;
3+
4+
namespace Helper
5+
{
6+
public static class WebHelpers
7+
{
8+
public static string GetClientAddress() =>
9+
Newtonsoft.Json.JsonConvert.SerializeObject(new { Verb = HttpVerbs.Get, Address = HttpContext.Current.Request.UserHostAddress });
10+
}
11+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<packages>
3+
<package id="Microsoft.AspNet.Mvc" version="5.2.7" targetFramework="net472" />
4+
<package id="Microsoft.AspNet.Razor" version="3.2.7" targetFramework="net472" />
5+
<package id="Microsoft.AspNet.WebPages" version="3.2.7" targetFramework="net472" />
6+
<package id="Microsoft.Web.Infrastructure" version="1.0.0.0" targetFramework="net472" />
7+
<package id="Newtonsoft.Json" version="6.0.5" targetFramework="net472" />
8+
</packages>

0 commit comments

Comments
 (0)