Search code examples
c#asp.netasp.net-web-apiasp.net-web-api-helppages

Customizing the "Resource Description" section of a ASP.NET Web API help page


I'm using ASP.NET Web API and it conveniently automatically generates documentation for my API, but some of it doesn't make sense.

Take the below screenshot as an example.

Screenshot

This is an endpoint to GET a user by their ID, and in the Resource Description section it's showing a table which shows the user model's properties because my controller action has the [ResponseType(typeof(User))] annotation.

Firstly, in my actual controller action, I'm stripping out the Password property before displaying results to the user in order to not expose sensitive information. So the table given in the Resource Description section is incorrect, it's saying my API returns fields that it doesn't.

Secondly, under the Additional Information column it's showing the validation rules that go along with the User model. Handy, but not at all relevant in this case as this endpoint is for GETing a user, not POSTing one.

So, my question is how can I customize this Resource Description table to specify myself what fields get returned, and hide the EF validations?

I've currently commented my controller action like this:

/// <summary>
/// Get a single user identified by ID.
/// </summary>
/// <param name="userId">The ID of the user.</param>
/// <returns>A data collection about the user.</returns>
[ResponseType(typeof(User))]
[Route("api/v1/users/{userId}", Name="GetUser")]
[HttpGet]
public IHttpActionResult GetUser(int userId)
{
    // ...
}

and I've configured the help pages to read the documentation from an XML file which gets built from these /// comments when I build the project.

Thanks!


Solution

  • In a traditional MVC application, view models are the models that are returned from your controller to the view engine. In a Web API application, the view model is the model exposed to the API consumer.

    As it is right now, you are using your data model as the view model.

    There are many reasons to separate view models from data models:

    1. Security: ensure that sensitive data (such as passwords) are not accidentally exposed
    2. Data differences between the Web API interface and the database data (for example, a enum in web API interface vs. int in database).
    3. Helps ensure the web API interface remains consistent even if internal data structures change.
    4. Allows you to differentiate data between GET and POST methods. For example, perhaps certain data is determined at the time of POSTing, such as record creation date. That data could be returned from GET, but you don't want it included in the POST.

    You've hit reasons #1 and #2.

    Your solution should be:

    1. Create a new class as your view model. Right now, you have a User data model class. Create a UserViewModel class (name it whatever you want).
    2. Add members to this class that should be exposed to the user. Do not include Password in your case.
    3. Add annotations that would be appropriate to be seen in the auto-generated help.
    4. Copy the data from the User class to the UserViewModel class and return the UserViewModel class from your controller.