Skip to content

Commit 8a97ad8

Browse files
committed
Require nullable parameter type when route parameter is optional. Close #32
1 parent 76fc8c4 commit 8a97ad8

File tree

3 files changed

+52
-3
lines changed

3 files changed

+52
-3
lines changed

AspNetCoreAnalyzers.Tests/ASP003ParameterSymbolTypeTests/CodeFix.cs

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
namespace AspNetCoreAnalyzers.Tests.ASP003ParameterTypeTests
1+
namespace AspNetCoreAnalyzers.Tests.ASP003ParameterSymbolTypeTests
22
{
33
using Gu.Roslyn.Asserts;
44
using Microsoft.CodeAnalysis.CodeFixes;
@@ -72,7 +72,7 @@ public IActionResult GetId(byte id)
7272

7373
[TestCase("int?")]
7474
[TestCase("Nullable<int>")]
75-
public void WhenNullableAndNotOptional(string parameter)
75+
public void RemoveNullableWhenNotOptional(string parameter)
7676
{
7777
var code = @"
7878
namespace ValidCode
@@ -106,6 +106,45 @@ public IActionResult GetId(int id)
106106
return this.Ok(id);
107107
}
108108
}
109+
}";
110+
AnalyzerAssert.CodeFix(Analyzer, Fix, ExpectedDiagnostic, code, fixedCode);
111+
}
112+
113+
[Test]
114+
public void MakeNullableToMatchOptional()
115+
{
116+
var code = @"
117+
namespace ValidCode
118+
{
119+
using System;
120+
using Microsoft.AspNetCore.Mvc;
121+
122+
[ApiController]
123+
public class OrdersController : Controller
124+
{
125+
[HttpGet(""api/orders/{id?}"")]
126+
public IActionResult GetId(↓int id)
127+
{
128+
return this.Ok(id);
129+
}
130+
}
131+
}";
132+
133+
var fixedCode = @"
134+
namespace ValidCode
135+
{
136+
using System;
137+
using Microsoft.AspNetCore.Mvc;
138+
139+
[ApiController]
140+
public class OrdersController : Controller
141+
{
142+
[HttpGet(""api/orders/{id?}"")]
143+
public IActionResult GetId(int? id)
144+
{
145+
return this.Ok(id);
146+
}
147+
}
109148
}";
110149
AnalyzerAssert.CodeFix(Analyzer, Fix, ExpectedDiagnostic, code, fixedCode);
111150
}

AspNetCoreAnalyzers.Tests/ASP003ParameterSymbolTypeTests/ValidCode.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
namespace AspNetCoreAnalyzers.Tests.ASP003ParameterTypeTests
1+
namespace AspNetCoreAnalyzers.Tests.ASP003ParameterSymbolTypeTests
22
{
33
using Gu.Roslyn.Asserts;
44
using Microsoft.CodeAnalysis.Diagnostics;

AspNetCoreAnalyzers/Analyzers/AttributeAnalyzer.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,16 @@ templateParameter.Constraints is ImmutableArray<RouteConstraint> constraints &&
209209
correctConstraint = GetCorrectConstraintType(constraint);
210210
return correctType != null;
211211
}
212+
213+
if (constraint.Span.Equals("?", StringComparison.Ordinal) &&
214+
parameterSymbol.Type.IsValueType &&
215+
parameterSymbol.Type.OriginalDefinition.SpecialType != SpecialType.System_Nullable_T)
216+
{
217+
correctType = parameterSymbol.Type.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat) + "?";
218+
constraintLocation = constraint.Span.GetLocation();
219+
correctConstraint = string.Empty;
220+
return true;
221+
}
212222
}
213223

214224
if (!constraints.TryFirst(x => x.Span.Equals("?", StringComparison.Ordinal), out _) &&

0 commit comments

Comments
 (0)