3

How can I have this simple Route:

http://domain.com/Calendar/Unsubscribe/my@email.com

I have a route that looks like:

routes.MapRoute(
    "Unsubscribe", 
    "Calendar/Unsubscribe/{subscriber}", 
    new { 
       controller = "Calendar", 
       action = "Unsubscribe", 
       subscriber = "" }
);

and my action is:

public ActionResult Unsubscribe(string subscriber)
{
    ...
}

Without any parameters, like http://domain.com/Calendar/Unsubscribe/ works fine, but soon I add the email, I get a 404 page :(

Is there any trick I have to do?

Thank you

balexandre
  • 73,608
  • 45
  • 233
  • 342
  • IIS or Cassini? Do you have the default route? – Darin Dimitrov Nov 29 '10 at 19:56
  • @Darin IIS, under Cassini works like a charm ! :( live url: http://julekal.dk/sony/Calendar/Unsubscribe/email@domain.com – balexandre Nov 29 '10 at 19:59
  • This is a specific case of more general issue: if the last part of URL path looks like file name to IIS (contains dot and "extension") then it treats this URL as link to a static file. http://stackoverflow.com/questions/11728846/dots-in-url-causes-404-with-asp-net-mvc-and-iis – baSSiLL Apr 21 '16 at 11:38

6 Answers6

7

Try adding a trailing slash to the url http://domain.com/Calendar/Unsubscribe/my@email.com/ without changing the routing rules.

If you still want to avoid adding the trailing slash and you have URL Rewrite available, you could add a rewrite rule into the web.config

<system.webServer>
  <rewrite>
    <rules>
      <rule name="Fix Unsubscribe emails route" stopProcessing="true">
        <match url="^(Calendar/Unsubscribe/.*@.*)$" />
        <action type="Rewrite" url="{R:1}/" />
      </rule>
    </rules>
  </rewrite>
</system.webServer>

You could also write a better regular expression than the one I provided for the sake of readability.

You could also try to reorder your route params like /Calendar/my@email.com/Unsubscribe so that the e-mail is not the last param.

Jani Hyytiäinen
  • 5,293
  • 36
  • 45
  • @balexandre this is not an MVC issue. The issue is that the request isn't even reaching the routing. Like you said, Cassini works, IIS not. So, this cannot be done through routes. At least not without reorganizing the route so, that email is not last and IIS lets your app handle it. If that cannot be done, then easiest fix is through rewrite which can be done through IIS Manager. – Jani Hyytiäinen Mar 26 '14 at 13:21
  • you do understand that my question was 4 years ago... right? and I did resolved back them... was a route issue... – balexandre Mar 26 '14 at 17:45
  • @balexandre Well sure, but I fought today several hours with this issue on Win2012R2/IIS8.5/MVC5 and there was not much help with google. However your question seemed to bump up every now and then so I thought I'd provide my resolution in hopes of saving other peoples' time. Oh, and this time it was not in the routing. The request never got that far. – Jani Hyytiäinen Mar 26 '14 at 17:56
  • Thanks for the first part of this answer, I had a similar issue where I was trying to pass through an email address as part of the route and without the trailing slash it was throwing a 404. Yay!! :) – Jen Jul 03 '14 at 00:25
  • Thanks, this worked. Although not if you have a `@using (Html.BeginForm` on the page. If you change that to a normal html form tag in the cshtml then it works. – VDWWD Aug 20 '19 at 09:42
1

I think this should do it.

routes.MapRoute(
"Unsubscribe", 
"Calendar/Unsubscribe/{subscriber}", 
   new { 
   controller = "Calendar", 
   action = "Unsubscribe"
   }
    new { subscriber =  @"\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*" }
);
Robin Maben
  • 22,194
  • 16
  • 64
  • 99
  • 1
    Your regex is pathetically short and inadequate ;). To properly adhere to the RFC, the regex is absolutely gigantic (and pointless). Take a look at this nonsense: http://www.ex-parrot.com/~pdw/Mail-RFC822-Address.html !!! If you want to validate the email address, it would be better to write an IConstraint and attempt to construct a MailAddress. http://msdn.microsoft.com/en-us/library/591bk9e8.aspx – spender Nov 29 '10 at 20:04
  • 2
    @spender: Well, I believe, the point here is not the regex for valid email id but rather how to use it with your `routes` which is why I posted whatever came across as convenient and readable. – Robin Maben Nov 29 '10 at 20:07
1

I tried it in default home controllor and working with no error

_http://localhost:64718/home/index/a.b@email.com

Welcome to ASP.NET MVC! a.b@email.com

public ActionResult Index(string id)    
{    
    ViewModel.Message = "Welcome to ASP.NET MVC!   " + id;    
    return View();    
}

No changes in defaultroute-MVC.

do you have any other routes defined before Unsubscribe which will match same route

David Rönnqvist
  • 56,267
  • 18
  • 167
  • 205
swapneel
  • 3,061
  • 1
  • 25
  • 32
  • nop, goes ok ... dang, there must be something that I'm not seeing right, maybe tomorrow with a fresh pair of eyes :) – balexandre Nov 29 '10 at 20:53
0

you don't need to add new rote! I tried it in Asp.Net Mvc4 application without any new routes and it worked. you can check email in Unsubscribe Method. I think it's better to do that.

good luck!

ahmadali shafiee
  • 4,350
  • 12
  • 56
  • 91
0

Try removing the default empty string for subscriber.

bmancini
  • 2,028
  • 15
  • 21
0

The @ symbol is a reserved character in URLs:

http://en.wikipedia.org/wiki/Percent-encoding

Try encoding it; Thusly, your new url would be:

http://domain.com/Calendar/Unsubscribe/my%40email.com
spender
  • 117,338
  • 33
  • 229
  • 351