__Note__: This behavior is after today's check-in of 'direct-routes' in webapi's attribute routing.
__Scenario__: User views the apis he is exposing in HelpPage.
__Issue__: HelpPage depends on ApiExplorer internally. ApiExplorer is not returning any api descriptions which are required to show up information on help page.
__Reason__: Before today's check-in, attribute routing used to create defaults for the 'controller' and 'action' variables into the defaults dictionary which ApiExplorer uses to generate descriptions, but currently we are not doing that instead only creating data tokens with the action descriptors.
__Example__ (following are how the routes might look like in route table for the attributed controller below...note the empty defaults):
("routeName", "api/values", new { }, new { httpMethod = HttpMethodConstraints[GET] }, dataTokens: new { actions = [] });
("routeName", "api/values", new { }, new { httpMethod = HttpMethodConstraints[POST] }, dataTokens: new { actions = [Post(String value)] });
("routeName", "api/values/apidescriptions", new { }, new { httpMethod = HttpMethodConstraints[GET] }, dataTokens: new { actions = [] });
("routeName", "api/values/{id}", new { }, new { httpMethod = HttpMethodConstraints[GET] }, dataTokens: new { actions = [GetSingle(Int32 id)] });
("routeName", "api/values/{id}", new { }, new { httpMethod = HttpMethodConstraints[PUT] }, dataTokens: new { actions = [Put(Int32 id, String value)] });
("routeName", "api/values/{id}", new { }, new { httpMethod = HttpMethodConstraints[DELETE] }, dataTokens: new { actions = [Delete(Int32 id)] });
```
[RoutePrefix("api/values")]
public class ValuesController : ApiController
{
[HttpGet("apidescriptions")]
public int GetApiDescriptionsCount()
{
return Configuration.Services.GetApiExplorer().ApiDescriptions.Count;
}
[HttpGet("")]
public IEnumerable<string> GetAll()
{
return new string[] { "value1", "value2" };
}
[HttpGet("{id}")]
public string GetSingle(int id)
{
return "value";
}
[HttpPost("")]
public void Post([FromBody]string value)
{
}
[HttpPut("{id}")]
public void Put(int id, [FromBody]string value)
{
}
[HttpDelete("{id}")]
public void Delete(int id)
{
}
}
```
__Attached__ a standalone Katana selfhost repro.
Comments: Verified.
__Scenario__: User views the apis he is exposing in HelpPage.
__Issue__: HelpPage depends on ApiExplorer internally. ApiExplorer is not returning any api descriptions which are required to show up information on help page.
__Reason__: Before today's check-in, attribute routing used to create defaults for the 'controller' and 'action' variables into the defaults dictionary which ApiExplorer uses to generate descriptions, but currently we are not doing that instead only creating data tokens with the action descriptors.
__Example__ (following are how the routes might look like in route table for the attributed controller below...note the empty defaults):
("routeName", "api/values", new { }, new { httpMethod = HttpMethodConstraints[GET] }, dataTokens: new { actions = [] });
("routeName", "api/values", new { }, new { httpMethod = HttpMethodConstraints[POST] }, dataTokens: new { actions = [Post(String value)] });
("routeName", "api/values/apidescriptions", new { }, new { httpMethod = HttpMethodConstraints[GET] }, dataTokens: new { actions = [] });
("routeName", "api/values/{id}", new { }, new { httpMethod = HttpMethodConstraints[GET] }, dataTokens: new { actions = [GetSingle(Int32 id)] });
("routeName", "api/values/{id}", new { }, new { httpMethod = HttpMethodConstraints[PUT] }, dataTokens: new { actions = [Put(Int32 id, String value)] });
("routeName", "api/values/{id}", new { }, new { httpMethod = HttpMethodConstraints[DELETE] }, dataTokens: new { actions = [Delete(Int32 id)] });
```
[RoutePrefix("api/values")]
public class ValuesController : ApiController
{
[HttpGet("apidescriptions")]
public int GetApiDescriptionsCount()
{
return Configuration.Services.GetApiExplorer().ApiDescriptions.Count;
}
[HttpGet("")]
public IEnumerable<string> GetAll()
{
return new string[] { "value1", "value2" };
}
[HttpGet("{id}")]
public string GetSingle(int id)
{
return "value";
}
[HttpPost("")]
public void Post([FromBody]string value)
{
}
[HttpPut("{id}")]
public void Put(int id, [FromBody]string value)
{
}
[HttpDelete("{id}")]
public void Delete(int id)
{
}
}
```
__Attached__ a standalone Katana selfhost repro.
Comments: Verified.