Latest

Microsoft’s ASP.Net Web API 2.2 allows you to easily create REST style APIs on an IIS website. Microsoft has some great documentation on how to get started with it, so I won’t rehash that here. Instead, I’m going to go a little deeper into some powerful features that can be used with Web API.

  • Part 1 – Customizing auto-generated documentation
  • Part 2 – HTTP Response Codes (this article)
  • Part 3 – HTTP Error Codes from Exceptions
  • Part 4 – OData URL Query Options
  • Part 5 – DTO Transformations and Automapper
  • Part 6 – Testing with EF Rollbacks across the Web API wire

Using Appropriate HTTP Response Codes

When building an HTTP REST API, you should use appropriate HTTP response codes to indicate the status of a response. This uses the semantics of HTTP to communicate the status rather than inventing something new. Here are the three response codes I use most often:

  • HTTP 200 – Everything is OK
  • HTTP 201 – Something was created
  • HTTP 404 – Something could not be found

I only explicitly do this for methods that return a single object. For Web API methods that return a collection, I don’t worry about what’s written in this blog post. That’s because if I successfully return a collection, Web API will by default return HTTP 200 OK. If it can’t find any items, I return an empty collection, which still by default returns HTTP 200 OK. And if there is an error, the error handling filter returns the appropriate HTTP Status code for the error (more details on this in next week’s post).

To return the appropriate HTTP response codes, there are 3 steps:

  • 1. Change the return type of your Web API action to IHttpActionResult.
  • 2. Wrap your return value in one of the helper methods, such as Ok()

After following these steps, you might notice that the auto-generated documentation (see part 1 of this series) can no longer figure out the type of the data being returned by your API method. Thankfully, there is a helpful attribute to give the documentation generator a hint: ResponseType. Add this attribute to your method and your Documentation should pick up the response type for the method. Note that you can include this attribute multiple times with different types listed, which can be helpful if a single API method has several possible return types.

  • 3. Add ResponseType attribute to the API Method
[ResponseType(typeof(Order))]
public IHttpActionResult GetOrder(int orderId)
{
    var order = orderFinder.FindOrder(orderId);  
    if (order == null)
        return NotFoundResult(Request);
    else
        return Ok(order);
}

In addition to Ok(), there are other methods including BadRequest(), NotFoundResult(), Created(), and more. If you can’t find the HTTP Status code that you want to use, you can use the generic one, which allows you to use any of the 48 codes in the System.Net.HttpStatusCode enum.

return new StatusCodeResult(HttpStatusCode.Moved, Request);

Microsoft’s ASP.Net Web API 2.2 allows you to easily create REST style APIs on an IIS website. Microsoft has some great documentation on how to get started with it, so I won’t rehash that here. Instead, I’m going to go a little deeper into some powerful features that can be used with Web API.

  • Part 1 – Customizing auto-generated documentation (this article)
  • Part 2 – HTTP Response Codes
  • Part 3 – HTTP Error Codes from Exceptions
  • Part 4 – OData URL Query Options
  • Part 5 – DTO Transformations and Automapper
  • Part 6 – Testing with EF Rollbacks across the Web API wire

Auto-generated Documentation

API documentation is notoriously difficult to keep up to date. After you finish writing or updating a method on the API, you must then go to your documentation and make updates to it that correspond to the changes you made to the API. It’s easy to forget, and it’s hard to find the time. But Web API has the built-in ability to automatically generate help documentation pages for you. To set it up, follow the documentation at http://www.asp.net/web-api/overview/creating-web-apis/creating-api-help-pages.

As part of the setup, make sure that your API project is configured to output the XML documentation file. To do this, right-click on your API project, click properties, then open the ‘Build’ tab and verify that it is configured to generate the XML documentation file:

This will cause an XML file to be placed in the App_Data folder of your API project when you build your project. This XML file is the data source for the auto-generated documentation. The file should end up at ApiProjectFolder\App_Data\MyApiProject.XML.

How does it document your API? It uses reflection to find out where your API controllers are, the inputs and outputs for the actions on those controllers, and the properties on those inputs and outputs. And if you’ve added XML comments to your controllers, actions, model classes, or model class properties, those XML comments automatically show up in the generated documentation. When something changes in a method or on a model and you need to update the documentation for it, all you have to do is update the XML comments that are right beside it in your code. This makes it significantly easier to keep your documentation up to date.

A Proper introduction for your documentation

After installing the documentation generator, I wanted to customize the main landing page for the documentation , which is set up by default at /Help on a project’s site. This was very simple – all I had to do was edit \Areas\HelpPage\Views\Help\Index.cshtml. You can add whatever HTML you want here to introduce your API, provide links to other resources, adding a getting started guide for your API consumers, etc. Doing so can make it significantly easier for someone else to consume your API.

Ordering the Controllers

By default, the list of API methods at /Help shows the controllers in a seemingly arbitrary fashion. I wanted the documentation for the controllers to list them in a particular order that made sense for our application. Making this happen is a 3 part process:

  1. Open \Areas\HelpPage\Controllers\HelpController.cs. In there, find the Index method, and at the beginning of that method, add some lines of code that add each controller in the order that you want them to be displayed in your documentation.
    displayOrder = new Dictionary<Type, int>();
    displayOrder.Add(typeof(IssueController), 1);
    displayOrder.Add(typeof(ArticleController), 2);
    displayOrder.Add(typeof(SubtitleController), 3);
    ViewBag.DisplayOrder = displayOrder;
  2. Open \Areas\HelpPage\Views\Help\Index.cshtml and edit the foreach loop at the very bottom to look like this:
    @foreach (var group in apiGroups
    .OrderBy(g => ViewBag.DisplayOrder.ContainsKey(g.Key.ControllerType) ?
      ViewBag.DisplayOrder[g.Key.ControllerType] : Int32.MaxValue))
    {
        @Html.DisplayFor(m => group, "ApiGroup")
    }
  3. Re-run your site, hit /Help to look at the help pages, and your controllers should be ordered as you directed.

What does this do? In step 1, you’re creating an dictionary that contains the order in which your controllers should be displayed. Then in part 2 you edit the razor cshtml page so that the apiGroups (each apiGroup represents a Web API controller) are sorted based on the data in the dictionary you created.

Documenting Models from a separate assembly

The API documentation displays data from an XML file, and that XML file is generated from the XML comments in your Web API project. This XML file only contains comments contained your Web API project – XML comments in other projects are ignored. If you like to keep your model classes in a separate project, those model classes will not be documented out of the box.

Here is how you can document your model classes that live a separate .csproj project:

  1. Open the project properties for your models project, go to the ‘Build’ tab, and tell the project to generate XML documentation on build. Make note of where this file will be saved. Also note that these settings could be different for each build configuration, so you might need to set these settings for multiple build configurations (Debug, Release, etc.).

    This will cause an XML file to be placed in the root folder of your Models project when you build your project. The file should end up at ModelsProjectFolder\Foo.Models.XML.

  2. Open the project properties for your Web API project, and in the ‘Build Events’ tab, add this to the post-build script (all on one line):

    copy $(SolutionDir)Foo.Models\Foo.Models.XML
     $(ProjectDir)\App_Data\Foo.Models.XML

    This will copy the XML file that contains the documentation from your Models project to your API project, which will allow the API documentation generator to access the XML comments on your model classes. Foo.Models is the name of the project holding your Model classes, and \Models.XML is the folder and file name you specified in step 1. After post-build, you should have a file at ApiProjectFolder\App_Data\Foo.Models.XML.

  3. This works great – until you use web deploy to deploy your API project. When you do this, the extra XML file is ignored. To tell web deploy to deploy your documentation XML file, customize the configuration to deploy the models XML file as follows.

    Open the csproj file for your API project for editing. This is done by right-clicking on your API project in Solution Explorer, click ‘Unload Project’, then right-click on the API project again and click ‘Edit Project.’

    You should have an Import that looks like this:

    <Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" />

    After that line, add this, editing the names and locations of the XML files to match the ones in your project:

    <Target Name="CustomCollectXmlDocumentationFiles">
        <ItemGroup>
          <_CustomFiles Include="App_Data\MyApiProject.XML" />
          <_CustomFiles Include="App_Data\Foo.Models.XML" />
          <FilesForPackagingFromProject Include="%(_CustomFiles.Identity)">
            <DestinationRelativePath>App_Data\%(Filename)%(Extension)</DestinationRelativePath>
          </FilesForPackagingFromProject>
        </ItemGroup>
      </Target>

      <PropertyGroup>
        <CopyAllFilesToSingleFolderForPackageDependsOn>
          CustomCollectXmlDocumentationFiles;
          $(CopyAllFilesToSingleFolderForPackageDependsOn);
        </CopyAllFilesToSingleFolderForPackageDependsOn>

        <CopyAllFilesToSingleFolderForMsdeployDependsOn>
          CustomCollectXmlDocumentationFiles;
          $(CopyAllFilesToSingleFolderForMsdeployDependsOn);
        </CopyAllFilesToSingleFolderForMsdeployDependsOn>
      </PropertyGroup>

    Save the changes to your .csproj file, close the file, then right-click on your API project in Solution Explorer and click ‘Reload’

    This will instruct the Web Deploy packager to include both XML files when it deploys, which means the auto-generated documentation should include documentation for controllers, actions, classes and properties from both your API project and your Models project.

    Closing

    I hope this has helped you to see how to take the Web API auto generated documentation further than what is provided out of the box. Let me know if you enhance the documentation in other ways.

    References

    Including Extra Files with MSDeploy
    Deploying Extra Files
    Web API Documentation Tools
    Swagger – an better looking documentation generator
    Swashbuckle, a utility to help install Swagger

You’ve set up Entity Framework, and you’ve even written integration tests against your code. Your tests create all kinds of sample data in your test database (you aren’t running integration tests against your production database, are you?), and now you need to make sure that the sample data gets cleaned up so the database looks like it did before your test. You could try to do some code to cleanup your data after your test runs, but if your test fails, it can be hard to know exactly how to clean up your data because you can’t guarantee that the data is in a particular state.

There is a better way. I was chatting with @jeremy6d this morning, and he suggested that I use transactions that can be rolled back at the end of a test. The following is how to do so when using Entity Framework 6.

Continue Reading →

If you aren’t bundling and minifying your javascript and CSS files, you should. It can significantly improve the load time of your web application. And if you’re working in ASP.Net, Microsoft helps bundle and minify your files with their Web Optimization tools, available on NuGet.

If you want to learn how to use the ASP.Net Web Optimization tools, read these links:

There is just one extra note I want to add – when creating a bundle, don’t put a ‘.’ in the bundle name, or it will silently fail.

So don’t do this:
bundles.Add(new ScriptBundle("~/bundles/myfiles.js.min").Include(...);

Instead, do this:
bundles.Add(new ScriptBundle("~/bundles/myfiles").Include(...);