|
| 1 | +--- |
| 2 | +title: "CA1418: Use valid platform string (code analysis)" |
| 3 | +description: "Learn about code analysis rule CA1418: Use valid platform string" |
| 4 | +ms.date: 08/31/2021 |
| 5 | +ms.topic: reference |
| 6 | +f1_keywords: |
| 7 | + - "UseValidPlatformString" |
| 8 | + - "CA1418" |
| 9 | +helpviewer_keywords: |
| 10 | + - "UseValidPlatformString" |
| 11 | + - "CA1418" |
| 12 | +author: buyaa-n |
| 13 | +ms.author: bunamnan |
| 14 | +--- |
| 15 | +# CA1418: Validate platform compatibility |
| 16 | + |
| 17 | +| | Value | |
| 18 | +|-|-| |
| 19 | +| **Rule ID** |CA1418| |
| 20 | +| **Category** |[Interoperability](interoperability-warnings.md)| |
| 21 | +| **Fix is breaking or non-breaking** |Non-breaking| |
| 22 | + |
| 23 | +## Cause |
| 24 | + |
| 25 | +The platform compatibility analyzer requires a valid platform name and version. Violations are reported if the platform string provided to the <xref:System.Runtime.Versioning.OSPlatformAttribute> constructor consists of an unknown platform name or if the optional version part is invalid. |
| 26 | + |
| 27 | +## Rule description |
| 28 | + |
| 29 | +The platform compatibility attributes derived from <xref:System.Runtime.Versioning.OSPlatformAttribute> use string literals for operating system (OS) platform names with an optional version part. The string should consist of a known platform name and either no version part or a valid version part. |
| 30 | + |
| 31 | +The known platform names list is populated from two places: |
| 32 | + |
| 33 | +- The `PlatformName` part of <xref:System.OperatingSystem> guard methods named `OperatingSystem.Is<PlatformName>[VersionAtLeast]()`. For example, guard method <xref:System.OperatingSystem.IsWindows?displayProperty=nameWithType> adds `Windows` to the known platform names list. |
| 34 | +- The project's MSBuild item group of `SupportedPlatform` items, including the default [MSBuild SupportedPlatforms list](https://github.com/dotnet/sdk/blob/main/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.SupportedPlatforms.props). This is the project specific knowledge of known platforms. It allows class library authors to add more platforms into the known platforms list. For example: |
| 35 | + |
| 36 | + ```XML |
| 37 | + <ItemGroup> |
| 38 | + <SupportedPlatform Include="PlatformName" /> |
| 39 | + </ItemGroup> |
| 40 | + ``` |
| 41 | + |
| 42 | +If the platform string contains a *version* part, it should be a valid <xref:System.Version> with the following format: `major.minor[.build[.revision]]`. |
| 43 | + |
| 44 | +### Violations |
| 45 | + |
| 46 | +- `Solaris` is an **unknown** platform name because it's not included in the default [MSBuild SupportedPlatforms list](https://github.com/dotnet/sdk/blob/main/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.SupportedPlatforms.props) and there's no guard method named `OperatingSystem.IsSolaris()` in the <xref:System.OperatingSystem> class. |
| 47 | + |
| 48 | + ```csharp |
| 49 | + [SupportedOSPlatform("Solaris")] // Warns: The platform 'Solaris' is not a known platform name. |
| 50 | + public void SolarisApi() { } |
| 51 | + ``` |
| 52 | + |
| 53 | +- `Android` is a **known** platform because there is a <xref:System.OperatingSystem.IsAndroid?displayProperty=nameWithType> guard method in the <xref:System.OperatingSystem> type. However, the version part is not a valid version. It should have at least two integers separated by a dot. |
| 54 | + |
| 55 | + ```csharp |
| 56 | + [UnsupportedOSPlatform("Android10")] // Warns: Version '10' is not valid for platform 'Android'. Use a version with 2-4 parts for this platform. |
| 57 | + public void DoesNotWorkOnAndroid() { } |
| 58 | + ``` |
| 59 | + |
| 60 | +- `Linux` is a **known** platform because it is included in the default [MSBuild SupportedPlatforms list](https://github.com/dotnet/sdk/blob/main/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.SupportedPlatforms.props), and there's also a guard method named <xref:System.OperatingSystem.IsLinux?displayProperty=nameWithType>. However, there are no versioned guard methods like `System.OperatingSystem.IsLinuxVersionAtLeast(int,int)` for the `Linux` platform, therefore no version part is supported on Linux. |
| 61 | + |
| 62 | + ```csharp |
| 63 | + [SupportedOSPlatform("Linux4.8")] // Warns: Version '4.8' is not valid for platform 'Linux'. Do not use versions for this platform. |
| 64 | + public void LinuxApi() { } |
| 65 | + ``` |
| 66 | + |
| 67 | +## How to fix violations |
| 68 | + |
| 69 | +- Change the platform to a known platform name. |
| 70 | + |
| 71 | +- If the platform name is correct and you want to make it a known platform, then add it to the MSBuild SupportedPlatforms list in your project file: |
| 72 | + |
| 73 | + ```XML |
| 74 | + <ItemGroup> |
| 75 | + <SupportedPlatform Include="Solaris" /> |
| 76 | + </ItemGroup> |
| 77 | + ``` |
| 78 | + |
| 79 | + ```csharp |
| 80 | + [SupportedOSPlatform("Solaris")] // No warning |
| 81 | + public void SolarisApi() { } |
| 82 | + ``` |
| 83 | + |
| 84 | +- Fix the invalid version. For example, for `Android`, `10` is not a valid version, but `10.0` is valid. |
| 85 | + |
| 86 | + ```csharp |
| 87 | + // Before |
| 88 | + [UnsupportedOSPlatform("Android10")] // Warns: Version '10' is not valid for platform 'Android'. Use a version with 2-4 parts for this platform. |
| 89 | + public void DoesNotWorkOnAndroid() { } |
| 90 | + |
| 91 | + // After |
| 92 | + [UnsupportedOSPlatform("Android10.0")] // No warning. |
| 93 | + public void DoesNotWorkOnAndroid() { } |
| 94 | + ``` |
| 95 | + |
| 96 | +- If the platform doesn't support a version, remove the version part. |
| 97 | + |
| 98 | + ```csharp |
| 99 | + // Before |
| 100 | + [SupportedOSPlatform("Linux4.8")] // Warns: Version '4.8' is not valid for platform 'Linux'. Do not use versions for this platform. |
| 101 | + public void LinuxApi() { } |
| 102 | + |
| 103 | + // After |
| 104 | + [SupportedOSPlatform("Linux")] // No warning. |
| 105 | + public void LinuxApi() { } |
| 106 | + ``` |
| 107 | + |
| 108 | +## When to suppress warnings |
| 109 | + |
| 110 | +Using an unknown platform name or an invalid version is not recommended. However, you can suppress these diagnostics by the usual means (`<NoWarn>`, .editorconfig file, or `#pragma`), for example: |
| 111 | + |
| 112 | +```csharp |
| 113 | +#pragma warning disable CA1418 |
| 114 | +[SupportedOSPlatform("platform")] |
| 115 | +#pragma warning restore CA1418 |
| 116 | +public void PlatformSpecificApi() { } |
| 117 | +``` |
| 118 | + |
| 119 | +## See also |
| 120 | + |
| 121 | +- [CA1416 Platform compatibility analyzer](ca1416.md) |
| 122 | +- [Platform compatibility analyzer (conceptual)](../../../standard/analyzers/platform-compat-analyzer.md) |
| 123 | +- [Interoperability rules](../../../framework/interop/index.md) |
0 commit comments