0

In the name of God

Hi all. I'm creating registration for my mvc 5 website in VS 2017.It has Email confirmation in it. the URL link for activation will be received completely in Email. when I click , it works and it exactly comes to my controller on the correct ActionMethod but I don't know why the activationCode is null! :| While before it worked correctly, I mean the Activation code was not null. I don't know what happend to it! Image enter image description here

Any help will be appreciated.

Edited:

 public class RouteConfig
{
    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        routes.MapRoute(
       name: "Password",
       url: "{controller}/{action}/{passwordResetCode}",
       defaults: new { controller = "Authentication", action = "ResetPassword" }
   );
        routes.MapRoute(
       name: "Activation",
       //url: "{controller}/{action}/{activationCode}",
       url: "Authentication/VerifyAccount/{activationCode}", 
       defaults: new { controller = "Authentication", action = "VerifyAccount" }
   );

        routes.MapRoute(
            name: "Default",
            url: "{controller}/{action}/{id}",
            defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
        );
    }
}
  • Please provide us with an example of the URL sent to the user email beside the action which receive this url and display the code page – Mahmoud Heretani Apr 27 '18 at 09:31
  • var verifyURL = "/Authentication/VerifyTheAccount/" + activationCode; var link = Request.Url.AbsoluteUri.Replace(Request.Url.PathAndQuery, verifyURL); Example:http://localhost:0000/Authentication/VerifyTheAccount/5fd21531-cbd7-4a41-9522-839f32c50300 – Atefeh Mohammadpoor Apr 27 '18 at 09:33
  • and inside the controller you should accept a parameter of name id and the type id GUID, beside that check your route to see whether if it accepts {id} parameter – Mahmoud Heretani Apr 27 '18 at 09:45
  • @MahmoudHeretani thanks for your attention to my question. I edited the question and I've put another image in it. Would you please have a look? – Atefeh Mohammadpoor Apr 27 '18 at 09:52
  • @MahmoudHeretani can you please give me an example. I think I have to put the route on the Action. but don't know what to write correctly. – Atefeh Mohammadpoor Apr 27 '18 at 09:56
  • You can check the example in the first answer – Mahmoud Heretani Apr 27 '18 at 10:42

2 Answers2

1

In order to achieve what you need you have to change the action parameter name to id or you can add extra route to your RouteConfig as following:

    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        routes.MapRoute(
           name: "Activation",
           url: "{controller}/{action}/{activationCode}",
           defaults: new { controller = "Authentication", action = "VerifyTheAccount" }
       );

        routes.MapRoute(
            name: "Default",
            url: "{controller}/{action}/{id}",
            defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
        );

    }

Note that the order of routes definition is very important.

Now when running the application you will get the following results: Debug result

And inside the browser: enter image description here

Mahmoud Heretani
  • 555
  • 1
  • 6
  • 17
  • WOW...Thanks a million. You really saved my day. Hope to get to whatever nice wishes you have. – Atefeh Mohammadpoor Apr 27 '18 at 10:54
  • @ MahmoudHeretani Hi again. your solution worked correctly. But when I added another route like " routes.MapRoute( name: "Password", url: "{controller}/{action}/{passwordResetCode}", defaults: new { controller = "Authentication", action = "ResetPassword" } );" The previous route doesn't work. I mean it again gets null value. Whenever I want to call its method I bring its route to the top of the other routes manually! And it gets work! You know I have to change each route's priority when I want to call its method. O.O Any Idea? Thanks In advance... – Atefeh Mohammadpoor Apr 28 '18 at 21:18
  • Wrong! Both routes are identical - the both accept between zero and 3 segments (the `Default` route will never be hit) –  Apr 30 '18 at 07:32
  • Please remove all routes and keep the default route, beside that change your all parameter names from passwordResetCode and activationCode to Id this should do the trick – Mahmoud Heretani Apr 30 '18 at 11:54
1

Your default route accepts a parameter named id, not activationCode. You either need to change the controller method to

public ActionResult VerifyTheAccount(string id)

and change the link to set the id, for example (from your comments)

var verifyURL = "/Authentication/VerifyTheAccount/" + activationCode

or using the preferred Url.Action() method

var verifyURL = '@Url.Action("VerifyTheAccount", "Authentication", new { id = activationCode })

Alternatively you need to create a specific route definition before the DefaultRoute

routes.MapRoute(
   name: "Activation",
   url: "Authentication/VerifyTheAccount/{activationCode}",
   defaults: new { controller = "Authentication", action = "VerifyTheAccount" }
);

routes.MapRoute(
    name: "Default",
    url: "{controller}/{action}/{id}",
    defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
  • well I did the same. But no answer I got. – Atefeh Mohammadpoor Apr 30 '18 at 08:08
  • Sorry, I do not understand you comment. What do you mean _But no answer I got._? –  Apr 30 '18 at 08:09
  • Y.W.C I didn't get any answer. You know? Now I understood that it's better to specify each actionMerhod's route on top of it and don't change the default Rout.config. But I don't know what to write exactly on top of my actionMethods. Do you know? – Atefeh Mohammadpoor Apr 30 '18 at 08:18
  • Exactly as per my answer - you create a specific route before the default - in your case it has `url: "Authentication/VerifyTheAccount/{activationCode}",` –  Apr 30 '18 at 08:20
  • on top of the Action method? like VerifyTheAcount? – Atefeh Mohammadpoor Apr 30 '18 at 08:23
  • Sorry, but I do not understand what you are saying. Use the code I gave you exactly. –  Apr 30 '18 at 08:25
  • The thing that you wrote is exactly what I have in my project. it still sends null value to my VerifyAccount. Because I have the bellowing code on top of it: routes.MapRoute( name: "PasswordReset", url: "Authentication/ResetPassword/{passwordResetCode}", defaults: new { controller = "Authentication", action = "ResetPassword", passwordResetCode = = UrlParameter.Optional } ); – Atefeh Mohammadpoor Apr 30 '18 at 08:35
  • No it is not! Look very carefully at the first route - in particular the url - it is NOT `url: "{controller}/{action}/{activationCode}",` - it is **url: "Authentication/VerifyTheAccount/{activationCode}"** –  Apr 30 '18 at 08:37
  • There is a difference - in the answer you accepted (which is wrong) - the first route matches any url with 3 segments - e.g. it matches `/Home/Index/1` and the `Default` route will never be hit. But in my answer - only a url starting with `/Authentication/VerifyTheAccount` will match the 1st route. Any other url will not match and hit the `Default` route –  Apr 30 '18 at 08:40
  • please look at my question. I edited the Rout.Config like you said. but still it sends null value. – Atefeh Mohammadpoor Apr 30 '18 at 08:51
  • Now you have gone and added another route first which matches anything - (it has nothing to do with this question) - but it would need to be `url: "Authentication/ResetPassword/{passwordResetCode}",` - again it needs to be a specific route –  Apr 30 '18 at 09:00