@@ -203,6 +203,91 @@ public class Customer
203
203
await VerifyCS . VerifyAnalyzerAsync ( source , expectedDiagnostic ) ;
204
204
}
205
205
206
+ [ Fact ]
207
+ public async Task Route_Parameter_withNameChanged_viaFromRoute_whenNotParsable_Fails ( )
208
+ {
209
+ // Arrange
210
+ var source = $$ """
211
+ using Microsoft.AspNetCore.Builder;
212
+ using Microsoft.AspNetCore.Mvc;
213
+ var webApp = WebApplication.Create();
214
+ webApp.MapGet("/customers/{cust}", ({|#0:[FromRoute(Name = "cust")]Customer customer|}) => {});
215
+
216
+ public class Customer
217
+ {
218
+ }
219
+ """ ;
220
+
221
+ var expectedDiagnostic = new DiagnosticResult ( DiagnosticDescriptors . RouteParameterComplexTypeIsNotParsableOrBindable )
222
+ . WithArguments ( "customer" , "Customer" )
223
+ . WithLocation ( 0 ) ;
224
+
225
+ // Act
226
+ await VerifyCS . VerifyAnalyzerAsync ( source , expectedDiagnostic ) ;
227
+ }
228
+
229
+ [ Fact ]
230
+ public async Task Route_Parameter_withTwoReceivingHandlerParameters_Works ( )
231
+ {
232
+ // Arrange
233
+ var source = $$ """
234
+ using System;
235
+ using Microsoft.AspNetCore.Builder;
236
+ using Microsoft.AspNetCore.Mvc;
237
+ var webApp = WebApplication.Create();
238
+ webApp.MapGet("/customers/{cust}", ([FromRoute(Name = "cust")]Customer customer, [FromRoute(Name = "cust")]string customerKey) => {});
239
+
240
+ public class Customer
241
+ {
242
+ public static bool TryParse(string s, IFormatProvider provider, out Customer result)
243
+ {
244
+ result = new Customer();
245
+ return true;
246
+ }
247
+ }
248
+ """ ;
249
+
250
+ // Act
251
+ await VerifyCS . VerifyAnalyzerAsync ( source ) ;
252
+ }
253
+
254
+ [ Fact ]
255
+ public async Task Route_Parameter_withNameChanged_viaFromRoute_whenParsable_Works ( )
256
+ {
257
+ // Arrange
258
+ var source = $$ """
259
+ using System;
260
+ using Microsoft.AspNetCore.Builder;
261
+ using Microsoft.AspNetCore.Mvc;
262
+ var webApp = WebApplication.Create();
263
+ webApp.MapGet("/customers/{cust}", ({|#0:[FromRoute(Name = "cust")]Customer customer|}) => {});
264
+
265
+ public class Customer : IParsable<Customer>
266
+ {
267
+ public static Customer Parse(string s, IFormatProvider provider)
268
+ {
269
+ if (TryParse(s, provider, out Customer customer))
270
+ {
271
+ return customer;
272
+ }
273
+ else
274
+ {
275
+ throw new ArgumentException(s);
276
+ }
277
+ }
278
+
279
+ public static bool TryParse(string s, IFormatProvider provider, out Customer result)
280
+ {
281
+ result = new Customer();
282
+ return true;
283
+ }
284
+ }
285
+ """ ;
286
+
287
+ // Act
288
+ await VerifyCS . VerifyAnalyzerAsync ( source ) ;
289
+ }
290
+
206
291
[ Fact ]
207
292
public async Task Route_Parameter_withBindAsyncMethodThatReturnsTask_of_T_Fails ( )
208
293
{
@@ -489,7 +574,7 @@ public class Customer
489
574
}
490
575
491
576
[ Fact ]
492
- public async Task Handler_Parameter_withWellknownTypes_Works ( )
577
+ public async Task Handler_Parameter_withWellKnownTypes_Works ( )
493
578
{
494
579
// Arrange
495
580
var source = $$ """
@@ -538,6 +623,108 @@ public async Task Handler_Parameter_with_FromService_Attribute_Works()
538
623
539
624
public class MyService
540
625
{
626
+ }
627
+ """ ;
628
+
629
+ // Act
630
+ await VerifyCS . VerifyAnalyzerAsync ( source ) ;
631
+ }
632
+
633
+ [ Fact ]
634
+ public async Task Handler_Parameter_withServiceInterface_Works ( )
635
+ {
636
+ // Arrange
637
+ var source = $$ """
638
+ using System;
639
+ using Microsoft.AspNetCore.Http;
640
+ using Microsoft.AspNetCore.Builder;
641
+
642
+ var webApp = WebApplication.Create();
643
+ webApp.MapGet("/weatherforecast", (HttpContext context, IDownstreamWebApi downstreamWebApi) => {});
644
+
645
+ // This type doesn't need to be parsable because it should be assumed to be a service type.
646
+ public interface IDownstreamWebApi
647
+ {
648
+ }
649
+ """ ;
650
+
651
+ // Act
652
+ await VerifyCS . VerifyAnalyzerAsync ( source ) ;
653
+ }
654
+
655
+ [ Fact ]
656
+ public async Task Route_Parameter_withAbstractBaseType_Works ( )
657
+ {
658
+ // Arrange
659
+ var source = $$ """
660
+ using System;
661
+ using Microsoft.AspNetCore.Http;
662
+ using Microsoft.AspNetCore.Builder;
663
+
664
+ var builder = WebApplication.CreateBuilder(args);
665
+ var app = builder.Build();
666
+
667
+ app.MapGet("/", () => "Hello World!");
668
+ app.MapGet("/{customer}", (BaseCustomer customer) => { });
669
+ app.Run();
670
+
671
+ public abstract class BaseCustomer : IParsable<BaseCustomer>
672
+ {
673
+ public static BaseCustomer Parse(string s, IFormatProvider? provider)
674
+ {
675
+ return new CommercialCustomer();
676
+ }
677
+
678
+ public static bool TryParse(string? s, IFormatProvider? provider, out BaseCustomer result)
679
+ {
680
+ result = new CommercialCustomer();
681
+ return true;
682
+ }
683
+ }
684
+
685
+ public class CommercialCustomer : BaseCustomer
686
+ {
687
+
688
+ }
689
+ """ ;
690
+
691
+ // Act
692
+ await VerifyCS . VerifyAnalyzerAsync ( source ) ;
693
+ }
694
+
695
+ [ Fact ]
696
+ public async Task Route_Parameter_withInterfaceType_Works ( )
697
+ {
698
+ // Arrange
699
+ var source = $$ """
700
+ using System;
701
+ using Microsoft.AspNetCore.Http;
702
+ using Microsoft.AspNetCore.Builder;
703
+
704
+ var builder = WebApplication.CreateBuilder(args);
705
+ var app = builder.Build();
706
+
707
+ app.MapGet("/", () => "Hello World!");
708
+ app.MapGet("/{customer}", (ICustomer customer) => { });
709
+ app.Run();
710
+
711
+ public interface ICustomer
712
+ {
713
+ public static ICustomer Parse(string s, IFormatProvider? provider)
714
+ {
715
+ return new CommercialCustomer();
716
+ }
717
+
718
+ public static bool TryParse(string? s, IFormatProvider? provider, out ICustomer result)
719
+ {
720
+ result = new CommercialCustomer();
721
+ return true;
722
+ }
723
+ }
724
+
725
+ public class CommercialCustomer : ICustomer
726
+ {
727
+
541
728
}
542
729
""" ;
543
730
0 commit comments