Extending your WebAPI documentation

As I already mentioned in a previous post, you can use the Microsoft.AspNet.WebApi.HelpPage NuGet package to generate a human-friendly documentation for your WebAPI directly from your source code. Because the NuGet package installs its full source code, you can customize the generated help pages with a few simple steps.

For example lets assume you designed your API that in case of any error all actions return an error code with the associated error message, and you store the possible errors in a different enum for every action. And of course you want to display these error cases in you API documentation!

Using a custom attribute – which I call here ErrorCodeType – you can connect the error code enum (here MyErrorCodeEnum) to the action on metadata level:

[ErrorCodeType(typeof(MyErrorCodeEnum))]

To display this information on the help pages, follow these steps:

 

1. Create a new class which will describe a single error case. Let’s call it ErrorCodeDescription and place it into the Models folder:

public class ErrorCodeDescription
{
  public int Code { get; set; }
  public string Message { get; set; }
}

 

2. The HelpPageApiModel.cs file contains the view-model which carries the data for the help page. Add a new property to this class which will contain all error cases in a list:

public List<ErrorCodeDescription> ErrorResponses { get; set; }

 

3. The GenerateApiModel method in the HelpPageConfigurationExtensions.cs file is responsible to build the view-model. You can find the VM in the apiModel variable which has the GenerateApiModel type. Here you can create and call a new custom method which retrieves your custom attribute and builds the ErrorResponses list like this:

private static void GenerateErrorResponses(HelpPageApiModel apiModel)
{
  ErrorCodeTypeAttribute attribute = apiModel.ApiDescription.ActionDescriptor
    .GetCustomAttributes<ErrorCodeTypeAttribute>().FirstOrDefault();
  Type enumType = attribute.ErrorCodeEnumType;
  string[] names = Enum.GetNames(attribute.ErrorCodeEnumType);

  foreach (string name in names)
  {
    apiModel.ErrorResponses.Add(new ErrorCodeDescription
    {
      Code = (int) Enum.Parse(enumType, name),
      Message = "TODO"
    });
  }
}

 

4. The Views/Help/DisplayTemplates/HelpPageApiModel.cshtml view is responsible for rendering the view-model. Add the following block to the view which delegates the rendering of the ErrorResponses list to the ErrorResponses partial view:

@if (Model.ErrorResponses.Any()) 
{ 
  <h3>Error Responses</h3> 
  @Html.DisplayFor(m => m.ErrorResponses, "ErrorResponses") 
}

 

5. Finally you have to create the ErrorResponses.cshtml file in the same folder. This partial view will receive a List<ErrorCodeDescription> instance as its @model and it is totally up to you how you want to transform it to a human-friendly HTML page.

 

At first it may seem too complicated, but in reality the steps are very logical and totally worth the time understanding it.

 

Technorati-címkék: ,
Categories: WebDev Tags:

Running custom code before and after tests

if you ever wrote a unit test in Visual Studio you probably heard of the [TestClass] and [TestMethod] attributes, that you can use to annotate classes and methods which contain tests. You can use similar attributes to decorate methods, which should run before and after the tests:

Methods decorated with the TestInitialize and TestCleanup attributes are executed before and after each and every test.

Methods decorated with the ClassInitialize and ClassCleanup attributes are executed before the first test and after the last test in the current class.

Methods decorated with the AssemblyInitialize and AssemblyCleanup attributes are executed before the first test and after the last test in the current assembly.

The last two can be particularly useful if you do Continuous Integration.

 

Technorati-címkék: ,
Categories: Testing, Visual Studio Tags:

Defining a GUID type in XSD

September 30, 2014 Leave a comment

It often happens that an element or an attribute in an XML document contains a GUID value. Because XML documents are useless without the corresponding XSD, it also often happens, that you have to define a GUID in XSD. Although XSD has support for several built-in types, unfortunately GUID is not one of them, and you have to use the classic regex solution:

<xs:schema ...>

  <xs:simpleType name="guid">
    <xs:restriction base="xs:string">
      <xs:pattern value="[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-
[0-9a-fA-F]{4}-[0-9a-fA-F]{12}" />
    </xs:restriction>
  </xs:simpleType>

After this you can refer to your new guid type just like the built-in ones:

<xs:attribute name="id" type="guid" use="required" />

Note that the regex pattern does not have $ and ^  characters in the beginning and in the end, because the pattern should always match the full value.

 

Technorati-címkék: ,
Categories: Data, WebDev Tags:

HTTPS: Do. Or do not. There is no try.

September 25, 2014 Leave a comment

Last summer I had the chance to visit Bologna, Italy, and I was happy to see that there is free wifi service in the airport. I probably had to be suspicious from the beginning, but it all started to be strange for me, when I saw this “welcome” page in the browser after connecting:

airport-ssl-warning

According to the message, the site’s security certificate is “a bit” invalid. Actually it could be more invalid only if it were already revoked.

If you decide to continue you will see this website of the airport:

airport-webpage

Really original design. Right, Bologna is not a huge metropolis, but I’m pretty sure it would be easy to find a student of the local university, who could click together a prettier website during a weekend.

This page made me curious and I could quickly find out, that the website has nothing to do with accessing the public internet.

There are many unusual and suspicious aspects here:

  • Certificate
  • IP address
  • Design
  • Phone number collection

This was the moment when I stood up and started to look for Troy Hunt and his Pineapple :)

Most of these concerns of me could be swept away with a single valid SSL certificate. But these invalid certificates do not guarantee anything, except nervous average users and pro users who are worrying about the security of their data.

If you do HTTPS, please do it correctly. Or don’t do it at all. Don’t try.

 

Technorati-címkék: ,
Categories: Security Tags:

JSON or not JSON: that is the question

September 11, 2014 Leave a comment

When you write unit tests for a REST API, you probably want to test whether the given response is in the expected format. For example you want to ensure, that the response string is a valid JSON or not.

You can find a very simple tip on StackOverflow and in other blogs as well: just check whether the first character of the response is a < or { character, because JSON is about Object Notation, right? The problem with this approach is not only that it does not perform a thorough analysis, but also that its basic statement is simply not true. According to json.org, a JSON can also contain only a single value, the specification does not require it to be an object or an array at all:

json-value

So I love JSON, 123, true and false are all valid JSON strings.

Unfortunately I could not find a simple IsValidJson method, but I could come up with this solution using Newtonsoft JSON.NET library:

try
{
    JToken.Parse(input);
    return true;
}
catch (JsonReaderException)
{
    return false;
}

Is there a better solution?

 

Technorati-címkék: ,,
Categories: .NET, WebDev Tags: , ,

IP filtering in IIS running in the Amazon cloud

September 10, 2014 Leave a comment

You can setup highly scalable webservices very easily in the Amazon EC2 cloud: just create two new virtual machines, connect them to a load balancer and you’re done! The dark clouds will begin to gather over your head, when you realize that the carefully setup IP filtering does not work in IIS, and anyone can access your website.

The problem is that the IIS running in the virtual machine sees the load balancer as the client, and not the original browser. (Obviously, IP filtering would work perfectly for that internal address, but I’m pretty sure you don’t need that.) If you don’t believe me, check your IIS log files.

Thankfully Amazon load balancers support the Proxy protocol which forwards the IP address of the real client in the X-Forwarded-For HTTP request header. By default IIS doesn’t log the value of this field, but you can add it to your logs with a few clicks:

iis-proxy-logging

The second good news is that you can configure IIS to use the X-Forwarded-For header for IP filtering. In IIS 7 you can do this with the Dynamic IP Restriction module, and from IIS 8 you can get this functionality built into the IP Address and Domain Restrictions module. It is not enabled by default, but you can activate it with a single click:

iis-proxy-mode

 

Technorati-címkék: ,,
Categories: Cloud, Security Tags:

Mixed content warning

August 18, 2014 1 comment

It is so sad, when a webpage falls apart in the browser, like this one in Chrome:

mixed content chrome

Why is that? Oh, isn’t it obvious? The explanation is there, let me help you:

mixed content chrome warning small

It is called the mixed content warning, and although it is a warning, it is very easy to miss. Let’s see the same page in Firefox:

mixed content FF

Do you get it? Here it is:

mixed content FF blocked small

Internet Explorer is not so gentle, it immediately calls the user’s attention:

mixed content warning

Although you don’t have to search for a shield icon (which is one of the most overused symbol in the IT history) here, because you immediately receive a textual message, the situation is not really better. Average users don’t understand this message and the real cause behind it. What’s more, not only users don’t get it, but also web developers don’t understand the security consequences, otherwise there won’t be any page with this warning at all.

It is so easy to get rid of the mixed content warning: just ensure that if you load the page via https:// protocol, then you must load all referenced content (yes, all of them) via https as well. If you have a single http:// URL in your page, then the browser will trigger the mixed content warning. If you load content from a third party domain and you cannot use relative URLs, then start your reference URLs with “//”, which tells the browser to use the same protocol which was used to load the page itself. It is called the “protocol relative”, “scheme relative” or “scheme-less relative” URL, and you can find its description already in the RFC 3986 (dated January 2005) which specifies the URI syntax. Thankfully all browsers understand it as well.

It is time to fix these pages, and let the browsers sooner or later completely block these poorly implemented pages.

 

Technorati-címkék: ,,
Categories: Security, WebDev Tags: ,
Follow

Get every new post delivered to your Inbox.

%d bloggers like this: