A request for '/api/customers' is resulting in 400 Bad Request.
__Attached__ a katana selfhost repro.
__Reason__:
The problem seems to be happening because of the following piece of code in RouteCollectionRouteData.
```
public IDictionary<string, object> Values
{
get
{
// Keys is just a union of the Keys from the sub routes.
// We don't actually use the values, because different subroutes may have conflicting values.
// Action selection just needs to know which keys are present.
if (_values == null)
{
var dict = new HttpRouteValueDictionary();
foreach (var data in SubRouteDatas)
{
foreach (var kv in data.Values)
{
// Actual value doesn't matter. We just look for the presence of the key.
dict[kv.Key] = String.Empty;
}
}
dict[SubRouteDataKey] = SubRouteDatas;
_values = dict;
}
return _values;
}
}
```
__Error__:
```
StatusCode: 400, ReasonPhrase: 'Bad Request', Version: 1.1, Content: System.Net.Http.StreamContent, Headers:
{
Date: Tue, 20 Aug 2013 19:44:39 GMT
Server: Microsoft-HTTPAPI/2.0
Content-Length: 350
Content-Type: application/json; charset=utf-8
}
{"Message":"The request is invalid.","MessageDetail":"The parameters dictionary contains a null entry for parameter 'id'
of non-nullable type 'System.Int32' for method 'System.String GetCustomer(Int32)' in 'SampleOwinApp.CustomersController
'. An optional parameter must be a reference type, a nullable type, or be declared as an optional parameter."}
```
__Controller__:
```
[RoutePrefix("api/customers")]
[Route("{id?}")]
public class CustomersController : ApiController
{
public string GetAllCustomers()
{
return "GetAllCustomers";
}
public string GetCustomer(int id)
{
return "GetCustomer:" + id;
}
public string CreateCustomer([FromBody]string value)
{
return "CreateCustomer:" + value;
}
[HttpPut]
public string UpdateCustomer(int id, [FromBody]string value)
{
return "UpdateCustoemr:" + id + ":" + value;
}
public string DeleteCustomer(int id)
{
return "DeleteCustomer:" + id;
}
[Route("{id}/orders")]
public string GetOrdersOfCustomer(int id)
{
return "GetOrdersOfCustomer:" + id;
}
}
```
__Attached__ a katana selfhost repro.
__Reason__:
The problem seems to be happening because of the following piece of code in RouteCollectionRouteData.
```
public IDictionary<string, object> Values
{
get
{
// Keys is just a union of the Keys from the sub routes.
// We don't actually use the values, because different subroutes may have conflicting values.
// Action selection just needs to know which keys are present.
if (_values == null)
{
var dict = new HttpRouteValueDictionary();
foreach (var data in SubRouteDatas)
{
foreach (var kv in data.Values)
{
// Actual value doesn't matter. We just look for the presence of the key.
dict[kv.Key] = String.Empty;
}
}
dict[SubRouteDataKey] = SubRouteDatas;
_values = dict;
}
return _values;
}
}
```
__Error__:
```
StatusCode: 400, ReasonPhrase: 'Bad Request', Version: 1.1, Content: System.Net.Http.StreamContent, Headers:
{
Date: Tue, 20 Aug 2013 19:44:39 GMT
Server: Microsoft-HTTPAPI/2.0
Content-Length: 350
Content-Type: application/json; charset=utf-8
}
{"Message":"The request is invalid.","MessageDetail":"The parameters dictionary contains a null entry for parameter 'id'
of non-nullable type 'System.Int32' for method 'System.String GetCustomer(Int32)' in 'SampleOwinApp.CustomersController
'. An optional parameter must be a reference type, a nullable type, or be declared as an optional parameter."}
```
__Controller__:
```
[RoutePrefix("api/customers")]
[Route("{id?}")]
public class CustomersController : ApiController
{
public string GetAllCustomers()
{
return "GetAllCustomers";
}
public string GetCustomer(int id)
{
return "GetCustomer:" + id;
}
public string CreateCustomer([FromBody]string value)
{
return "CreateCustomer:" + value;
}
[HttpPut]
public string UpdateCustomer(int id, [FromBody]string value)
{
return "UpdateCustoemr:" + id + ":" + value;
}
public string DeleteCustomer(int id)
{
return "DeleteCustomer:" + id;
}
[Route("{id}/orders")]
public string GetOrdersOfCustomer(int id)
{
return "GetOrdersOfCustomer:" + id;
}
}
```