35

I have a WebApi controller with a method that looks like such:

[HttpGet]
[AcceptVerbs("GET")]
public HttpResponseMessage Run(string reportName, int someId, string someText, DateTime asOfDate, string username)

I have a custom route configured specifically for this action. When I navigate my browser to the web service, everything works fine, and the appropriate action is executed:

http://localhost:xxxx/ControllerName/Run/asdf/1/asdf/07-01-2012/user@domain.com

However, when I attempt to programatically call the web service using the HttpClient and executing a "Get" I get a 404 error. I don't get an error when the username parameter is not an email address. For example, when the username is just "user" everything works fine. Here is the sample code:

var url = "http://localhost:xxxx/ControllerName/Run/asdf/1/asdf/07-01-2012/user@domain.com"
var client = new System.Net.Http.HttpClient();
var response = client.Get(url);

//fails here with 404 error
response.EnsureSuccessStatusCode();

I have tried UrlEncoding the email address with no luck. Any advice is appreciated.

Matt Wolin
  • 701
  • 1
  • 8
  • 13
  • Try replacing @ by %40 -Edit- Just a complete random guess. -Edit2- UrlEncoding should have switched it for you so if what I told you works, you might wanna check at how you used UrlEncoding and possible parameters. – Pluc Aug 06 '13 at 16:47
  • 2
    Considering the complexity of your request you might want to use the `POST` verb and send a custom complex object instead. Then you also skip some other problems, such as the impossibility to pass the character `/` in any of the strings. – user1908061 Aug 06 '13 at 16:54
  • @Pluc, I gave your suggestion a shot with no success as expected since that is exactly what the urlecode was doing. Thanks tho. – Matt Wolin Aug 06 '13 at 17:02
  • @user1908061 I would like to keep with the GET if possible as it is easier to test through the browser. – Matt Wolin Aug 06 '13 at 17:03
  • 1
    @MattWolin Browser testability of a REST API should really not be your focus. Instead better use unit tests. If you need to test something manually, just submit requests using Fiddler or browser addons for this purpose. – user1908061 Aug 06 '13 at 17:11
  • Just check with Fiddler2 how this request is different from browser's request. – outcoldman Aug 06 '13 at 18:49
  • 5
    Probably too late, but for me it has worked to end the Url with a `/` - `https://localhost:xxxx/user@domain.com` does *not* work - `https://localhost:xxxx/user@domain.com/` *does* work – percebus Mar 17 '16 at 22:27
  • Look at this, for me the answer of Damitha works!!! [How to pass email as a parameter](https://stackoverflow.com/questions/12840849/how-to-pass-email-as-a-parameter-at-the-end-of-url-in-asp-net-mvc-web-api?noredirect=1&lq=1) – Elena Madarnas Feb 05 '20 at 10:33

4 Answers4

40

Just a quick thought... could the ".com" be causing the issue?

Ryan Ferretti
  • 2,891
  • 2
  • 27
  • 37
  • 29
    Wow, thanks! It was actually the '.' character causing issues and not the '@' symbol. After seeing this post: http://stackoverflow.com/questions/13298542/apicontroller-returns-404-when-id-contains-period I just added a trailing '/' in the route to the last parameter and it works like a charm. – Matt Wolin Aug 07 '13 at 16:50
22

This is because IIS is trying to map special characters. Adding the following to the web.config should fix the issue:

<system.webServer>  
     <modules runAllManagedModulesForAllRequests="true" />
</system.webServer>

More information here: http://www.iis.net/configreference/system.webserver/modules

Chris Pickford
  • 8,642
  • 5
  • 42
  • 73
DataPispor
  • 381
  • 3
  • 8
  • This is the fix I think we'll go with, although I'd like to see if there's any other issues that might arise because of it. – Codeacula Nov 03 '14 at 14:41
  • @Codeacula at worst performance since the managed modules will be used to serve static content. This will be a good thing if the content requires any kind of auth. – user2320464 Oct 08 '15 at 15:05
1

You need a basic URL query.

[Route("api/emails")]
public HttpResponseMessage Run(string email) {...}

GET api/emails?email=user@domain.com
JJJ
  • 32,902
  • 20
  • 89
  • 102
1

Adding the following to the web.config should not fix the complete issue:

<system.webServer>  
     <modules runAllManagedModulesForAllRequests="true" />
</system.webServer>

The solution no longer works as an extra path segment is used in the uri for me. https://localhost:xxxx/user@domain.com does work

https://localhost:xxxx/path/user@domain.com does not work

I google around and around and i understood that it is an extension. (.cs gives a different error as .com) and finaly find this: ASP.net MVC4 WebApi route with file-name in it

My solution was to add or change the following handler in the <handlers> section of your <system.webServer>:

<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" 
           path="*.*" 
           verb="*" 
           type="System.Web.Handlers.TransferRequestHandler" 
           preCondition="integratedMode,runtimeVersionv4.0" />

or change the path to path=*@*.*

Roberto B
  • 542
  • 5
  • 13