Doc/Handlers/MethodSelection

How methods defined on a handler are selected

The methods on a handler get selected through multiple stage in the pipeline. It's important to note that every method will get processed until only is left.

Filters

The first step of the selection process uses a list of filters to narrow down the number of methods being matched.

By default, two filters are automatically registered.

HttpMethodHandlerMethodSelector

  • All methods starting with the HTTP method name. For example, for a GET HTTP method, both a Get() and a GetCustomer() method will be selected.
  • All methods containing the HttpOperationAttribute with a matching HTTP method name.
UriNameHandlerMethodSelector
  • If the request URI is not associated with a name (through the AtUri().Named() method), all the methods will be selected.
  • If there is a URI name,
    • If there are methods with an HttpOperationAttribute with a ForUriName property matching the URI name, those methods will be selected
    • Otherwise, all the methods will be selected

URI parameter matching

In the following step, the pipeline will take the URI parameters defined in the URI templates, and will try to assign the properties to the parameters of the method. An error is thrown if the parameterized portion of the URI can't be converted to the method parameter type.

In the following example, the value of the {page} URI template parameter will be assigned to the page parameter of the Get method. The parameters are matched by name.

ResourceSpace.Has.ResourcesOfType<Page>().AtUri("/pages/{page}")
...
public OperationResult Get(int page)

Class matching for POST operations

If an HTTP POST method contains form data in the body of the request, it can be matched to a Post method which defines an object parameter whose public property names match the form element names.

The following example first defines a simple HTML form, a CustomerPost class which matches some of those form elements, and a handler with a Post method using the CustomerPost class.

<form method="post" action="/customer">
    First Name: <input type="text" name="firstname" ><br>
    Last Name: <input type="text" name="lastname" ><br>
    <input type="submit">
</form>
...
ResourceSpace.Has.ResourcesOfType<CustomerPost>().AtUri("/customer").HandledBy<CustomerHandler>();
...
public class CustomerPost
{
    public string firstname { get; set; }
    public string lastname { get; set; }
    public int balance { get; set; } // will not affect selection
}
...
public class CustomerHandler
{
    public object Post(CustomerPost formdata)
    {
        return new CustomerResource(formdata.firstname, formdata.lastname);
    }
}