Best asp.net questions in June 2011

IIS doesn't recognise view model annotations

15 votes

I have a basic MVC view model with annotations, for example:

    [Required(ErrorMessage="Your Name Required")]
    [Display(Name = "Your Name")]
    [DataType(DataType.Text)]
    [MaxLength(120, ErrorMessage = "Must be under 120 characters")]                
    public String  YourName { get; set; }

I have a strongly-typed view based upon this view model. When I run the application locally, the following code generates "Your Name" label:

@Html.LabelFor(model => model.YourName)

When the application is deployed on IIS7 with .NET 4 application pool, the label says "YourName" (without a space).

This is very bizzare and I didn't come across this before. Does anybody have an idea what might be causing this?

Cache is cleared, this has been tested from a range of web clients and result is the same.

Edit:

@model MVC.Web.Models.ContactUsModel

<div>
    @Html.LabelFor(model => model.YourName)
    @Html.EditorFor(model => model.YourName)       
</div>

Edit 2 All annotations on that field are being ignored. There are other text type fields and they have the same issue. This is happening only on a live server. Live server is IIS 7 which has been configured over Plesk 10.2. Wondering whether this is a bug since I'm using MVC 3 RTM.

Edit 3 Within the same view model I have the Email property:

    [Required(ErrorMessage = "Your Email Is Required")]
    [Display(Name = "Your Email")]
    [RegularExpression(@"^\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$", ErrorMessage = "Your Email Is Invalid")]
    [DataType(DataType.Text)]
    public String FromEmail { get; set; }

This property is used within a view:

    <div>
        @Html.LabelFor(model => model.FromEmail)    
        @Html.EditorFor(model => model.FromEmail)        
    </div>

But it works perfectly fine :( So the email property works fine in both live and dev environment. Other properties work only in dev environment.

Edit 4 Removing MaxLength and MinLength annotations fixed the problem. I would still like to use MaxLength and MinLength annotations as part of my model validation routines though.

[MinLength(3, ErrorMessage = "Minimum 3 Characters")]
[MaxLength(30, ErrorMessage = "Maximum 30 Characters")]

MVC3 supports the [StringLength] attribute, while [MinLenght] and [MaxLength] come with Entity Framework. Could you try this instead of MaxLength?

[StringLength(120, ErrorMessage = "Must be under 120 characters")]  

How to design Date-of-Birth in DB and ORM for mix of known and unkown dates

10 votes

Note up front, my question turns out to be similar to SO question 1668172.


This is a design question that surely must have popped up for others before, yet I couldn't find an answer that fits my situation. I want to record date-of-birth in my application, with several 'levels' of information:

  • NULL value, i.e. DoB is unkown
  • 1950-??-?? Only the DoB year value is known, date/month aren't
  • ????-11-23 Just a month, day, or combination of the two, but without a year
  • 1950-11-23 Full DoB is known

The technologies I'm using for my app are as follows:

  • Asp.NET 4 (C#), probably with MVC
  • Some ORM solution, probably just Linq-to-sql but NHibernate's an option too
  • MSSQL Server 2008, at first just Express edition

Possibilities for the SQL bit that crossed my mind so far:

  • 1) Use one nullable varchar column e.g. 1950-11-23, and replace unkowns with 'X's, e.g. XXXX-11-23 or 1950-XX-XX
  • 2) Use three nullable int columns e.g. 1950, 11, and 23
  • 3) Use an int column for year, plus a datetime column for full known DoBs

For the C# end of this problem I merely got to these two options:

  • A) Use a string property to represent DoB, convert only for view purposes.
  • B) Use a custom(?) struct for DoB with three nullable integers
  • C) Use a nullable datetime alongside a nullable integer for year

The solutions seem to form matched pairs at 1A, 2B or 3C. Of course 1A isn't a nice solution, but it does set a baseline.

Any tips and links are highly appreciated. Well, if they're related, anyhow :)

Edit, about the answers: I marked one answer as accepted, because I think it will work for me. It's worth looking at the other answers too though, if you've stumbled here with the same question.

The SQL Side

My latest idea on this subject is to use a range for dates that are uncertain or can have different specificity. Given two columns:

DobFromDate (inclusive)
DobToDate (exclusive)

Here's how it would work with your scenarios:

Specificity   DobFromDate  DobToDate
YMD           2006-05-05    2006-05-06
YM            2006-05-01    2006-06-01
Y             2006-01-01    2007-01-01
Unknown       0000-01-01    9999-12-31
MD, M, D      Not supported with this scheme

Note that there's no reason this couldn't be carried all the way to hour, minute, second, millisecond, and so on.

Then when querying for people born on a specific day:

DECLARE @BornOnDay date = '2006-05-16'

-- Include lower specificity:
SELECT *
FROM TheTable
WHERE
   DobFromDate <= @BornOnDay
   AND @BornOnDay < DobToDate;

-- Exclude lower specificity:
SELECT *
FROM TheTable
WHERE
   DobFromDate = @BornOnDay
   AND DobToDate = DateAdd(Day, 1, @BornOnDay);

This to me has the best mix of maintainability, ease of use, and expressive power. It won't handle loss of precision in the more significant values (e.g., you know the month and day but not the year) but if that can be worked around then I think it is a winner.

If you will ever be querying by date, then in general the better solutions (in my mind) are going to be those that preserve the items as dates on the server in some fashion.

Also, note that if you're looking for a date range rather than a single day, with my solution you still only need two conditions, not four:

DECLARE
   @FromBornOnDay date = '2006-05-16',
   @ToBornOnDay date = '2006-05-23';

-- Include lower specificity:
SELECT *
FROM TheTable
WHERE
   DobFromDate <= @ToBornOnDay
   AND @FromBornOnDay < DobToDate;

The C# Side

I would use a custom class with all the methods needed to do appropriate date math and date comparisons on it. You know the business requirements for how you will use dates that are unknown, and can encode the logic within the class. If you need something before a certain date, will you use only known or unknown items? What will ToString() return? These are things, in my mind, best solved with a class.

Sessions mixed up on asp.net site

8 votes

I am analyzing a problem from an old asp.net site made by one of my colleagues who left the company some months ago.

The problem is that we a few times have expierenced that two users sessions are mixed up, so that if for example two users are logged in, one user sees the other users data. As it happens very rarely (once in a month or so) it is difficult to figure out what goes wrong.

I have now stepped through his code for authentication and it goes like this:

  1. The user enter username/password on public page and press submit
  2. On Page_Load on Masterpage the code checks in a mySql database that the username/password is valid, not expired etc and return a unique userid if ok
  3. The page then saves the loginpage in session like this (used for later logout): HttpContext.Current.Session(Consts.CCookieName_LoginUrl) = Request.RawUrl
  4. Then the userid is saved like this: FormsAuthentication.SetAuthCookie(userid, False)
  5. Then a redirect to the secure area is performed: Context.Response.Redirect(secureurl, False)
  6. In Page_Init of masterpage of secure area the userid is read by: userid = Context.User.Identity.Name
  7. the user data is loaded acording to the userid
  8. The user navigates the secure area, ie. step 6 - 7 is repeated
  9. The user suddently sees another users data

I have some ideas on what is going wrong, but would like to have some input before modifying the code, so please anyone?

It's hard to tell here. Have you configured Form Authentication?

This is the process you have to follow for Form Authentication: In your web.config you setup the authentication system:

<authentication mode="Forms">
    <forms loginUrl="Login.aspx" defaultUrl="Home.aspx" timeout="30" slidingExpiration="true" />
</authentication>

<authorization>
  <deny users="?"/>
</authorization>

Your login page (post-back) checks the credentials (not your master page). If the user is valid then you set the cookie:

FormsAuthentication.SetAuthCookie(userid, False)

and redirect to another page. Now, you have to set your principal reading the cookie here:

protected void Application_AuthenticateRequest(Object sender, EventArgs e) {
    if (HttpContext.Current.User != null) {
        if (Request.IsAuthenticated == true) {    
            // Debug#1            
            FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(Context.Request.Cookies[FormsAuthentication.FormsCookieName].Value);
            // In this case, ticket.UserData = "Admin"                
            string[] roles = new string[1] { ticket.UserData }; 
            FormsIdentity id = new FormsIdentity(ticket);
            Context.User = new System.Security.Principal.GenericPrincipal(id, roles);
            // Debug#2
        }
    }
}

Obviously, I've simplified, but this is the path you have to follow to do things properly.

StackOverflow like URL Routing

8 votes

Its my understanding that the questions in StackOverflow has the following format

http://stackoverflow.com/questions/{question-id}/{slug-made-from-question-title}

So basically the question is retrieved using the question-id. so whatever value I give the slug is immaterial.

First I would like to know whether this understanding is wrong :)

I have a URL

http://stackoverflow.com/questions/6291678/convert-input-string-to-a-clean-readable-and-browser-acceptable-route-data

Then I changed the slug manually like this.

http://stackoverflow.com/questions/6291678/naveen

But it changed to the original slug. Firebug showed me a permenant redirect 301 on the altered URL. How to implement this functionality?

You can do this with Response.RedirectPermanent available since ASP.NET 4.0:

http://msdn.microsoft.com/en-us/library/system.web.httpresponse.redirectpermanent.aspx

protected void Page_Load(object sender, EventArgs e)
{
    if(!IsPostBack)
    {
        string id = RouteData.Values["id"].ToString();
        string passedSlug = RouteData.Values["name"].ToString();
        //get the original slug from database / dymanic method
        string originalSlug = GetSlugFromID(id);

        if(!originalSlug.Equals(passedSlug))
        {
            var url = String.Format("~/test/{0}/{1}", id, originalSlug);
            Response.RedirectPermanent(url, true);
        }
    }
}

On an unrelated side note, would like to think Stack Overflow is not saving the slug at database. Its created dynamically from title using something like this. I just altered the title of my question and the slug changed. It will be un-necessary to store the slug in database as it is redundant to title.

ASP.NET Varying Trust Level Per-Page by Assembly?

8 votes

I have two web applications (pre-compiled sites), one is first-party and will run at full trust. Another is third-party and should run at partial trust (or with specific permissions).

TrustedAssembly.Web.Pages.MyPage should run in the full trust default AppDomain. UntrustedAssembly.Web.Pages.SomePage should run in a partial trust AppDomain.

Furthermore, if TrustedAssembly.Web.Pages.MyPage dynamically loads UntrustedAssembly.Web.Controls.SomeControl is it possible to run the control in partial trust and/or with specific permissions, while the page runs under full trust?

And vice versa, e.g. UntrustedAssembly.Web.Controls.SomePage dynamically loads TrustedAssembly.Web.Controls.MyControl, is it possible to run the control in full trust while the page runs under partial trust?

Update/FYI: This is .NET 4

Doing this is likely to be a bit tricky. Here are two possible lines of thought:

The first is to run the app in Medium trust, but to place anything that you want running in full trust in the GAC, and what you want running in partial trust in bin.

Note that in your 'vice versa' scenario, the trusted control may need to perform a security 'assert' before being able to perform full trust operations. e.g.

(new SecurityPermission(SecurityPermissionFlag.UnmanagedCode)).Assert();

The second line of thought is to run the app in Full trust, but then load any assembly that you want running in Medium trust using a custom Evidence. e.g.

var evidence = new Evidence();
// Initialize the Evidence
Assembly.LoadFrom(path, evidence);

But be aware that correctly setting up the Evidence object is not for the faint of heart, and I'm not sure I would go does that path.

Not a complete answer, but hopefully some ideas that can lead to one :)

viewstate: disabled

7 votes

What's the difference between:

  • ViewStateMode: Disabled / Enabled / Inherit
  • EnableViewState: True / False

It's in the properties of asp.net controls.

Thanks for the explanation.

EDIT

ViewStateMode

  • Enabled - Turns the ViewState On for this control
  • Disabled - Turns the ViewState Off for this control
  • Inherit - Inherits from the value of the parent control

EnableViewState

  • Overrides ViewStateMode, must be true for ViewStateMode to have meaning.

See: Minimizing viewstate- confused by `EnableViewState` and `ViewStateMode` in asp.net 4.0

ORIGINAL

Understanding ASP.NET View State

Gets or sets a value indicating whether the server control persists its view state, and the view state of any child controls it contains, to the requesting client. Control.EnableViewState Property

You can use the ViewStateMode property to enable view state for an individual control even if view state is disabled for the page. For more information about view state and control state, see the EnableViewState property. Control.ViewStateMode Property

Should I make my object properties nullable or use the CLR default values for each type?

7 votes

I have been trying to figure out the best way to handle default values. Setting a ID value to 0 makes sense, but if it is a money value or other that is not initially set, when you encounter it later in your code, it is impossible to tell if it has been set or was set to 0. If a money value is set to null, then you know it has not been set. Additionally, when dealing with the database, it is simple to know if you need to write a null value to a field vs trying to figure out if it is supposed to be null or not.

What is the accepted way to handle this?

Class MyModel
{
    public int Id {get;set;}
    public string Title {get;set;}
    public DateTime CreatedDate {get;set;}
    public bool IsActive {get;set;}

    //CLR will automatically set these values
    Public MyModel()
    {
        Id = 0; 
        Title = String.Empty;
        CreatedDate = "1/1/0001";
        IsActive = false;
    }
}

vs

Class MyModel
{
    public int? Id {get;set;}
    public string Title {get;set;}
    public DateTime? CreatedDate {get;set;}
    public bool? IsActive {get;set;}

    //CLR will automatically set these values
    Public MyModel()
    {
        Id = null; 
        Title = null;
        CreatedDate = null;
        IsActive = null;
    }
}

You can always mix approaches, depending on your domain.

static class ID
{
    public const int Unassigned = -1;
}

class MyModel
{
    public int Id { get; private set; }
    public string Title { get; set; }
    public DateTime CreatedDate { get; set; }
    public bool IsActive { get; set; }
    public bool? IsAwesome { get; set; }

    Model () 
    {
        // you may use "default" constants...
        Id = ID.Unassigned;
    }

    // you may use optional parameters or overloads
    public MyModel (string title,
        DateTime created = DateTime.Now, // default values may be concrete 
        bool? isAwesome = null)          // or nullable as well
        : this ()                        // and you can chain-call constructors!
    {
        Title = title ?? "<no title>";   // you don't always want null to come through
        CreatedDate = created;     
        IsAwesome = isAwesome;    
    }
}

// Possible usages:
var model = new MyModel ("Hello", new DateTime (2001, 1, 1));
var model = new MyModel ("world", isAwesome: true);
var model = new MyModel (null) {
    IsActive = true
};

It may make sense for some attributes to have null values, as in “not set”.

In your example, perhaps a model really doesn't have an Id before it is persisted to the database. If this is the case, and an id-less model makes sense in terms of business logic, a nullable Id is better than Id = 0. However, if your application never works with id-less models, and usually expects Id to equal something, it would be crazy to write

if (model.Id != null)

each time you want to do something with it.

In this case, you should probably go with Id = 0 by default.
You could also introduce a constant (as I've done above) though I wouldn't recommend it for anything but ids, and only in case they are heavily used by code elsewhere.

Again, everything depends on the domain.
Your job is to ensure that objects violating business rules can't be created easily.

How to comment a line of a XML file in C# with System.XML

6 votes

I need to comment and uncomment the 4th line of this XML file using System.XML properties:

<?xml version="1.0" encoding="utf-8"?>
    <configuration>    
        <system.web>
            <customErrors mode="On" defaultRedirect="som_url_here" />
        </system.web>
    </configuration>

Desired output:

<!-- <customErrors mode="On" defaultRedirect="som_url_here" /> -->

It's possible to achieve this without using a file reader/etc?

The node:

XmlNode xmlNodoCE = docWebConfig.DocumentElement.SelectSingleNode("system.web/customErrors");

You need to

  • load the file into an XmlDocument,
  • retrieve the node you want to comment,
  • create a comment node containing the XML content of your original node,
  • add this comment to the original's parent node just before the original node
  • remove it from its parent,
  • write the XmlDocument to a file (the same one).

    String xmlFileName = "Sample.xml";
    
    // Find the proper path to the XML file
    String xmlFilePath = this.Server.MapPath(xmlFileName);
    
    // Create an XmlDocument
    System.Xml.XmlDocument xmlDocument = new System.Xml.XmlDocument();
    
    // Load the XML file in to the document
    xmlDocument.Load(xmlFilePath);
    
    // Get the target node using XPath
    System.Xml.XmlNode elementToComment = xmlDocument.SelectSingleNode("/configuration/system.web/customErrors");
    
    // Get the XML content of the target node
    String commentContents = elementToComment.OuterXml;
    
    // Create a new comment node
    // Its contents are the XML content of target node
    System.Xml.XmlComment commentNode = xmlDocument.CreateComment(commentContents);
    
    // Get a reference to the parent of the target node
    System.Xml.XmlNode parentNode = elementToComment.ParentNode;
    
    // Replace the target node with the comment
    parentNode.ReplaceChild(commentNode, elementToComment);
    
    xmlDocument.Save(xmlFilePath);
    

Map entity to JSON using JavaScriptSerializer

6 votes

My entities are like this:

class Address
{
     public string Number { get; set; }
     public string Street { get; set; }
     public string City { get; set; }
     public string Country { get; set; }
}

class Person
{
     public string Name { get; set; }
     public int Age { get; set; }
     public Address PostalAddress { get; set; }
}

Person newPerson = 
    new Person()
    {
       Name = "Kushan",
       Age = 25,
       PostalAddress = 
           new Address()
           {
               Number = "No 25",
               Street = "Main Street",
               City = "Matale",
               Country = "Sri Lanka"
           }
    };

Now I wanna map this newPerson object into JSON object like this,

{ 
     "PER_NAME" : "Kushan",
     "PER_AGE" : "25",
     "PER_ADDRESS" : {
                          "ADD_NUMBER" : "No 25",
                          "ADD_STREET" : "Main Street",
                          "ADD_CITY" : "Matale",
                          "ADD_COUNTRY" : "Sri Lanka"
                     }
}

Note: Above is just an example.

What I need is, I need to customize the Key at the serializing time. by default it is taking property name as the key. I can't change property names. How to do this?

Also, is it possible to change to order of appearing key-value pairs in JSON obj.?

You need to add DataContract attributes to your classes and DataMember to the properties. Set Name property of DataMemeber attribute to your custom property name and Order property to define the order.

[DataContract]
public class Person
{
    [DataMember(Name = "PER_NAME", Order = 1)]
    public string Name { get; set; }

    [DataMember(Name = "PER_AGE", Order = 2)]
    public int Age { get; set; }

    [DataMember(Name = "PER_ADDRESS", Order = 3)]
    public Address PostalAddress { get; set; }
}

Then you can do this:

var newPerson = new Person()
{
    Name = "Kushan",
    Age = 25,
    PostalAddress = new Address()
    {
        Number = "No 25",
        Street = "Main Street",
        City = "Matale",
        Country = "Sri Lanka"
    }
};

MemoryStream stream = new MemoryStream();
DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(Person));
ser.WriteObject(stream, newPerson);

To check the result:

var result = Encoding.ASCII.GetString(stream.ToArray());

{"PER_NAME":"Kushan","PER_AGE":25,"PER_ADDRESS":{"ADD_NUMBER":"No 25","ADD_STREET":"Main Street","ADD_CITY":"Matale","ADD_COUNTRY":"Sri Lanka"}}

Why does everyone say dependency injection in ASP.NET webforms is hard when PageHandlerFactory and IHttpHandlerFactory exist?

6 votes

So I have a legacy webforms site and am working on making it easier to maintain. Chucking it away and rewriting it isn't an option.

IoC is obviously one of the first things it got, but this leaves me with the service-locator pattern and a bad taste, and the wondering of whether it could be done better.

Various people I've talked to online and off tell me that I could do property-injection with an HttpModule that scans a Page class for properties decorated with an Inject attribute or similar, but that sounds like a Reflection hit (cached, but still) on every request. Not appealing.

So I was looking at other options, and came across System.Web.IHttpHandlerFactory, which has apparently been in the framework since v2. One can remove the default *.aspx handler and replace it with one that uses a custom implementation, in httpHandlers web.config section.

So, the people I've talked to aren't dumb; I thought I'd ask here. Are there any gotchas with replacing the webforms PageHandlerFactory with an IoC-based implementation...?

It looks like it has both a CreateHandler and ReleaseHandler method, so life-style related memory leaks from the container keeping a reference to created components shouldn't be a problem...

Because of the way ASP.NET is designed, Page classes need to have a default constructor. When you want to use constructor injection, there is a way around this. You can make the default constructor protected and add a single public constructor that takes the dependencies as follows:

public partial class _Default : System.Web.UI.Page
{
    private IUserService service;

    protected _Default()
    {
    }

    public _Default(IUserService service)
    {
        this.service = service;
    }
}

This allows you to create a custom PageHandlerFactory and inject the dependencies in the constructor.

So this works, but there is a catch though. The _Default class you define is not the actual class ASP.NET uses. ASP.NET creates a new class that inherits from _Default. This new class builds a control hierarchy based on the markup in the .aspx file. This class looks a bit like this:

public class ASPGeneratedDefault : _Default
{
    public ASPGeneratedDefault() : base()
    {
    }

     protected override vor OnPreInit(object sender, EventArgs e)
     {
          // Building up control hierarchy.
     }
}

As you can see, the custom constructor hasn't been overridden in the ASPGeneratedDefault by ASP.NET. Because of this there is no way of letting a DI framework create this type for us. The way around this is to let ASP.NET create this type for us and invoke the non-default constructor of the _Default base class on that existing instance. Because this instance already exists, we must do this with reflection and this will fail when run in partial trust.

Besides that, this works for page classes, but not for user controls on the page. The code generator of ASP.NET news up those controls with their default constructor during the control hierarchy build up process. When you want this to work for them, you need your custom PageHandlerFactory to hook to the PreInit event of those controls, because during the time the page class is constructor, the related controls and user controls are not yet created. However, to register the PreInit event on them, you need to find those controls within the page class, and again we need to reflect over the page class. Because controls are stored in non-public instance fields, again this won't work in partial trust.

Whether or not it is a problem your application can not run in partial trust is up to you, but since the security model of .NET 4 has been simplified considerably, it is very easy to run web apps in partial trust and it is something I strive to do.

So in conclusion, it is possible to do so (see for instance this example), but because of the limitations of the ASP.NET Web Forms framework, you need to run in full trust to get it to work.

Best Practice for Storing and Updating External API Passwords

6 votes

I have a ASP.Net C# application that needs to connect to an external API using WebServices every 5 minutes.

The requirements of the External Webservice are as follows:

  • Username and Password are required
  • I must transmit the username and password with each webservice request
  • Passwords expire every 90 days and must be changed prior to the expiration date
  • Passwords cannot be changed manually (by human), my application must connect to a separate Password Change Webservice to change the password.
  • My application must generate each new password based on a set of rules.
  • Passwords can never be reused.
  • SSL, Certificates and Firewall IP restrictions are required

I have built all of the previous, but I currently have one issue. What is the best practice for storing the current and historical passwords?

Obviously storing the plaintext password is a bad solution. I need to be able to have my webservice read the password and transmit it with each request. I also need to be able to access all of the historical passwords to make sure that my newly generated password is not a duplicate.

Ideally, I would like to store each (encrypted) password in my database and decrypt it whenever I need to call the webservice. Is there a best practice I should be following? Should I encrypt each password using Microsoft.Practices.EnterpriseLibrary.Security.Cryptography.Cryptographer.EncryptSymmetric(..)?

Note: Unfortunately, I have no access to change the way the external API functions. I must follow the rules provided.

With regard to the password history I would go down one of two routes:

  1. As per your current plan, store passwords in file/db/config - suggest you use a hashing algorithm (as opposed to encryption) to compare the new password with stored password hashes for "equality".

  2. Don't bother storing password history at all - let the first attempt to the password change web service just fail if it chooses too, then resend with an alternative password. This way, you are not duplicating the business rules of the password change web service (for example, lets say they change it to allow you to re-use a password after 6 months time).

With regard to storing the current password: assuming you must send the password as plaintext, then yes, you should store it in encrypted form. There are many articles out there on how to do this. Or you could even encrypt a specific section of your config file such as seen here.

Why can't Asp.net MVC distinguish between two actions when they have different parameters?

5 votes

I am trying to have two different methods for account registration in my Asp.net MVC application, one for general users to register for and another for users who are registering with a specific registration token. Thus I have the following method signatures in my AccountController:

public virtual ActionResult Register () {...}

public virtual ActionResult Register (Guid registrationToken) {...}

However, when I go to http://localhost/Account/Register I get an exception that the current request is ambiguous between these two actions. I was under the impression that it would use the parameterless Register action if there was no registrationToken GET parameter passed in, otherwise it would use the 2nd.

Does this require special route configuration?

Would it be easier to have one method with a nullable parameter? This will also automatically solve your problem as it will not be ambiguous anymore:

public virtual ActionResult Register (Guid? registrationToken)
{
    if(registrationToken.HasValue)
    {
         // this is specific user
    }         
    else
    {
         // this is general user
    }
}