FromQuery: specifies that this attribute must come from the query string
1
2
3
4
5
6
7
8
9
10
[HTTPGet][Route("/api/projects/{pid}/tickets")]//slash at the start indicates from root rather than the controller route defined in the class-levelpublicIActionResultGetTicketFromProject(intpid,[FromQuery]inttid){if(tid==0){returnOk($"Reading all tickets belonging to project #{pid}");}else{returnOk($"Reading project {pid}, tickets #{id}");}}
Using a complex type:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
publicclassTicket{ [FromQuery(Name="tid")]publicintTicketId{get;set;} [FromRoute(Name="pid")]publicintProjectId{get;set;}}[HTTPGet("{id}")][Route("/api/projects/{pid}/tickets")]publicIActionResultGetTicketFromProject(Ticketticket){if(ticket.TicketId==0){returnOk($"Reading all tickets belonging to project #{ticket.ProjectId}");}else{returnOk($"Reading project {ticket.ProjectId}, tickets #{ticket.TickedId}");}}
publicclassTicket_EnsureDueDateForTicketOwner:ValidationAttribute{protectedoverrideValidationResultIsValid(Objectvalue,ValidationContextvalidationContext){varticket=validationContext.ObjectInstanceasTicket;if(ticket!=null&&!string.IsNullOrWhiteSpace(ticket.Owner)){if(!ticket.DueDate.HasValue){returnnewValidationResult("Due date is required when ticket has owner");}}returnValidationResult.Success;}}/**some code **/publicstringOwner{get;set;}[Ticket_EnsureDueDateForTicketOwner]publicDateTime?DueDate{get;set;}
publicclassValidateModelAttribute:ActionFilterAttribute{publicoverridevoidOnActionExecuting(ActionExecutingContextcontext){//custom validation on the endpointif(!context.ModelState.IsValid){context.ModelState.AddModelError("SomeKey","Key is missing");//short circuit the requestcontext.Result=newBadRequestObjectResult(context.ModelState);}}}[HttpPost][ValidateModelAttribute]publicIActionResultPost([FromBody]Ticketticket){returnOk(ticket);//automatically serializes the body into JSON}
Useful to short-circuit the rest of the pipeline such as during versioning and caching
1
2
3
4
5
6
7
8
9
10
11
publicclassVersion1DiscontinueResourceFilter:Attribute,IResourceFilter{publicvoidOnResourceExecuting(ResourceExecutingContextcontext){if(pathcontainsv1){contex.Result=newBadRequestObjectResut(new{Versioning=new[]{"This API Version is discontinued"}});}}}