Skip to content

Add resource naming breaking change for .NET Core 3.0 #17044

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

Merged
merged 9 commits into from
Feb 13, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions docs/core/compatibility/2.2-3.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -363,6 +363,14 @@ If you're migrating from version 2.2 to version 3.0 of .NET Core, ASP.NET Core,

***

## MSBuild

- [Resource manifest file name change](#resource-manifest-file-names)

[!INCLUDE[Resource file names](~/includes/core-changes/msbuild/3.0/resource-manifest-name.md)]

***

## Networking

- [Default value of HttpRequestMessage.Version changed to 1.1](#default-value-of-httprequestmessageversion-changed-to-11)
Expand Down
8 changes: 8 additions & 0 deletions docs/core/compatibility/2.2-3.1.md
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,14 @@ If you're migrating from version 2.2 to version 3.1 of .NET Core, ASP.NET Core,

***

## MSBuild

- [Resource manifest file name change](#resource-manifest-file-names)

[!INCLUDE[Resource file names](~/includes/core-changes/msbuild/3.0/resource-manifest-name.md)]

***

## Networking

- [Default value of HttpRequestMessage.Version changed to 1.1](#default-value-of-httprequestmessageversion-changed-to-11)
Expand Down
16 changes: 16 additions & 0 deletions docs/core/compatibility/msbuild.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
---
title: MSBuild breaking changes
description: Lists the breaking changes in MSBuild for .NET Core.
ms.date: 02/10/2020
---
# MSBuild breaking changes

The following breaking changes are documented on this page:

- [Resource manifest file name change](#resource-manifest-file-names)

## .NET Core 3.0

[!INCLUDE[Resource file names](~/includes/core-changes/msbuild/3.0/resource-manifest-name.md)]

***
2 changes: 2 additions & 0 deletions docs/core/compatibility/toc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@
href: /ef/core/what-is-new/ef-core-3.0/breaking-changes?toc=/dotnet/core/compatibility/toc.json&bc=/dotnet/breadcrumb/toc.json
- name: Globalization
href: globalization.md
- name: MSBuild
href: msbuild.md
- name: Networking
href: networking.md
- name: Visual Basic
Expand Down
82 changes: 82 additions & 0 deletions includes/core-changes/msbuild/3.0/resource-manifest-name.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
### Resource manifest file names

Starting in .NET Core 3.0, the generated resource manifest file name has changed.

#### Version introduced

3.0

#### Change description

Prior to .NET Core 3.0, when [DependentUpon](/visualstudio/msbuild/common-msbuild-project-items#compile) metadata was set for a resource (*.resx*) file in the MSBuild project file, the generated manifest name was *Namespace.Classname.resources*. When [DependentUpon](/visualstudio/msbuild/common-msbuild-project-items#compile) was not set, the generated manifest name was *Namespace.Classname.FolderPathRelativeToRoot.Culture.resources*.

Starting in .NET Core 3.0, when a *.resx* file is colocated with a source file of the same name, for example, in Windows Forms apps, the resource manifest name is generated from the full name of the first type in the source file. For example, if *Type.cs* is colocated with *Type.resx*, the generated manifest name is *Namespace.Classname.resources*. However, if you modify any of the attributes on the `EmbeddedResource` property for the *.resx* file, the generated manifest file name may be different:

- If the `LogicalName` attribute on the `EmbeddedResource` property is set, that value is used as the resource manifest file name.

Examples:

```xml
<EmbeddedResource Include="X.resx" LogicalName="SomeName.resources" />
-or-
<EmbeddedResource Include="X.fr-FR.resx" LogicalName="SomeName.resources" />
```

**Generated resource manifest file name**: *SomeName.resources* (regardless of the *.resx* file name or culture or any other metadata).

- If `LogicalName` is not set, but the `ManifestResourceName` attribute on the `EmbeddedResource` property is set, its value, combined with the file extension *.resources*, is used as the resource manifest file name.

Examples:

```xml
<EmbeddedResource Include="X.resx" ManifestResourceName="SomeName" />
-or-
<EmbeddedResource Include="X.fr-FR.resx" ManifestResourceName="SomeName.fr-FR" />
```

**Generated resource manifest file name**: *SomeName.resources* or *SomeName.fr-FR.resources*.

- If the previous rules don't apply, and the `DependentUpon` attribute on the `EmbeddedResource` element is set to a source file, the type name of the first class in the source file is used in the resource manifest file name. More specifically, the generated file name is *Namespace.Classname\[.Culture].resources*.

Examples:

```xml
<EmbeddedResource Include="X.resx" DependentUpon="MyTypes.cs">
-or-
<EmbeddedResource Include="X.fr-FR.resx" DependentUpon="MyTypes.cs">
```

**Generated resource manifest file name**: *Namespace.Classname.resources* or *Namespace.Classname.fr-FR.resources* (where `Namespace.Classname` is the name of the first class in *MyTypes.cs*).

- If the previous rules don't apply, `EmbeddedResourceUseDependentUponConvention` is `true` (the default for .NET Core), and there's a source file colocated with a *.resx* file that has the same base file name, the *.resx* file is made dependent upon the matching source file, and the generated name is the same as in the previous rule. This is the "default settings" rule for .NET Core projects.

Examples:

Files *MyTypes.cs* and *MyTypes.resx* or *MyTypes.fr-FR.resx* exist in the same folder.

**Generated resource manifest file name**: *Namespace.Classname.resources* or *Namespace.Classname.fr-FR.resources* (where `Namespace.Classname` is the name of the first class in *MyTypes.cs*).

- If none of the previous rules apply, the generated resource manifest file name is *RootNamespace.RelativePathWithDotsForSlashes.\[Culture.]resources*. The relative path is the value of the `Link` attribute of the `EmbeddedResource` element if it's set. Otherwise, the relative path is the value of the `Identity` attribute of the `EmbeddedResource` element. In Visual Studio, this is the path from the project root to the file in Solution Explorer.

#### Recommended action

If you're unsatisfied with the generated manifest names, you can:

- Modify your resource file metadata according to one of the previously described naming rules.

- Set `EmbeddedResourceUseDependentUponConvention` to `false` in your project file to opt out of the new convention entirely:

```xml
<EmbeddedResourceUseDependentUponConvention>false</EmbeddedResourceUseDependentUponConvention>
```

> [!NOTE]
> If the `LogicalName` or `ManifestResourceName` attributes are present, their values will still be used for the generated file name.

#### Category

MSBuild

#### Affected APIs

N/A
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ The default value of the <xref:System.Net.Http.HttpRequestMessage.Version?displa

#### Version introduced

.NET Core 3.0
3.0

#### Change description

Expand All @@ -25,8 +25,8 @@ Networking
- <xref:System.Net.Http.HttpRequestMessage.Version?displayProperty=fullName>

<!--
a def
### Affected APIs

#### Affected APIs

- `P:System.Net.Http.HttpRequestMessage.Version`

Expand Down