+1  A: 

You should use <match url="/users/([0-9]+)" /> and <match url="/users/([a-z]+)" ignoreCase="true" />, respectively, to match the complete id/user and not just their first letter/digit. But I don't know why your regex would have failed on a single digit, so there must be another issue, too.

As for your second question, I'm not sure I understand completely. How can you tell the difference between a folder name and a user name? Will a folder always have a trailing slash?

Tim Pietzcker
+2  A: 

The obvious problem is that your current regexes only match one character in the user name or one number. You'll need to add a plus quantifier inside the parentheses in order to match multiple letters or numbers. See this page for more info about regex quantifiers. Note that you won't be matching plain URLs like "/users/" (no ID or name). Make sure this is what you intended.

The other problem you're running into is that IIS evaluates rewrite rules starting from the first character after the initial slash. So your rule to match /users/([0-9]) won't match anything because when the regex evaluation happens, the URL looks like users/foo not /users/foo. The solution is to use ^ (which is the regex character that means "start of string") at the start of the pattern instead of a slash. Like this:

<rule name="ID">
    <match url="^users/([0-9]+)" />
    <action type="Rewrite" url="/User.aspx?id={R:1}" />
</rule>
<rule name="Name">
    <match url="^users/([a-z]+)" ignoreCase="true" />
    <action type="Rewrite" url="/Users.aspx?name={R:1}" />
</rule>

Note that you're choosing Users.aspx for one of these URLs and User.aspx (no plural) for the other. Make sure this is what you intended.

BTW, the way I figured these things out was by using IIS Failed Request Tracing to troubleshoot rewrite rules. This made diagnosing this really easy. I was able to make a test request and look through the trace to find where each rewrite rule is being evaluated (it's in a section of the trace called "PATTERN_MATCH". For the particular PATTERN_MATCH for one of your rules, I saw this:

-PATTERN_MATCH
Pattern /users/([0-9]+?)
InputURL users/1
Negate false
Matched false

Note the lack of the beginning slash.

Justin Grant
+1 for finding the fundamental problem besides the wrong regex :)
Tim Pietzcker