Opening a mobile app from a link: the Xamarin way (URL-Schemes)

Launching an app from within another app, from a mail link or from a link in a web page can be a very useful feature.

Social networks use this function a lot. However, all apps which have some “sharing” feature can benefit from it.

How to implement the URL schemes in Xamarin? We have to use two different methods for Android and iOS.

This is the task at hand:

– We have an app called superduperapp that should be opened whenever, on a user’s device, a URL as “superduperapp://my_code_is_here” is clicked by the user on their iPhone or Android phone (or: opened by another app on the same device);

– The data following the URL “protocol” (the string “my_code_is_here” in this example) is read by the app, which creates its data context based on that code.

This is one of those times in which Xamarin iOS and Xamarin Android implementations have little in common, since we’re touching the foundations of how the device operating system communicates and deals with the apps.

Xamarin for iOS URL Schemes:

As a first thing, we have to “decorate” the iOS app with the new URL scheme. We do this in the Info.plist file.

Xamarin Studio has a good editor for this file. You have to go to the “advanced tab” and add a “URL Type”. The URL scheme should contain the URL type you want to link your application to. In our case, since we would like superduperapp to be opened by URLs as “superduperapp://my_code_is_here”, our URL scheme will be “superduperapp”.

Xamarin Studio for iOS screenshot

How to edit Info.plist in Xamarin Studio

The “role” field is apparently ignored by iOS, but it’s supposed to mean:

Editor=app can read and write the type of files individuated by the URL
Viewer=can only view that file type;
None=cannot use it (I guess this option is used when an app is updated and we want to delete the file association)

As a second thing, we have to override the OpenUrl method of the Application delegate class:

public override bool OpenUrl (UIApplication application, NSUrl url,
string sourceApplication, NSObject annotation)
Console.WriteLine (url);
/* now store the url somewhere in the app’s context. The url is in the url NSUrl object. The data is in url.Host if the link as a scheme as superduperapp://something_interesting */
return true;

That’s it. If you store the url data in a persistent object, you can then use it in your ViewControllers. It is not very elegant, but it could be just sufficient to grab the code passed to the app with the “Host” property of the url, like this:

PersistantClass.CodeEntered=url.Host; //PersistantClass would be your custom class to hold data

To test, we create a web page with a link as this:

<a href=”superduperapp://my_code_is_here”>superduperapp_link</a>

which visually translates into this:

Link with custom URL schema to open our app

A link with a custom URL looks exactly as any link. In it, we might have a personal URL scheme, as superduperapp in our case

When we click on the link on the simulator, the iOS app opens (well, of course we must have installed it first). The app delegate reads the URL in the OpenUrl overridden method. Later, we display – as a test – the code extracted from the link:

this is how the code shows once we open the app via the custom URL

iPhone or iPad app done in Xamarin, opened by custom URL

Please note:

The application name does NOT have to be the same of the URL scheme. You can register your app “uncommonApp” to deal with any URL: BeautifulThings://, http:// (if you’re making a browser), whatever://

Xamarin for Android

In Android, the procedure to register an app to deal with a type of URL is (you figured that out already) completely different from that of iOS. We have to work on the AndroidManifest.xml file (contained in the /properties folder).

A typical AndroidManifest.xml file will look like a bit this (depending on the permissions and features the app needs):

<?xml version=”1.0″ encoding=”utf-8″?>
<manifest xmlns:android=”; android:versionCode=”1″ android:versionName=”1.0″ package=”superduperapp.superduperapp”>
<uses-sdk android:minSdkVersion=”19″ android:targetSdkVersion=”19″ />
<application android:label=”superduperapp”></application>
<uses-permission android:name=”android.permission.CAMERA” />

Our task here is to tell the operating system that a certain activity of the superduper app will be able to deal with the links that have a URL scheme as, for instance, superduper://my_code_is_here .

In the application tag, we have to add an indication to the activity and to the associated URL type.

The activity name goes in the android:name attribute of the application tag. The URL scheme name goes in the android:scheme attribute of the data tag inside the intent-filter, inside the activity, inside the application… like so:

<application android:label=”superduperapp”>
<activity android:icon=”@drawable/Icon” android:label=”superduperapp” android:name=”superduperapp.urlentryclass”>
<action android:name=”android.intent.action.VIEW” />
<category android:name=”android.intent.category.DEFAULT” />
<category android:name=”android.intent.category.BROWSABLE” />
<data android:scheme=”superduperapp” />

We install the app on the device (it works also on the emulator).

As we did with iOS, we open our emulator and navigate to the address that contains the link

<a href=”superduperapp://my_code_is_here”>superduperapp_link</a>

Link in android device

Link to open android app from custom link

When we click, our app opens on the Activity we indicated on the AndroidManifest.xml file (superduperapp.urlentryclass).

The class reads the code that is after the superduperapp:// “protocol” string in the Intent object, with this code:

[Activity (Label = “urlentryclass”)]
public class urlentryclass : Activity
protected override void OnCreate (Bundle bundle)
base.OnCreate (bundle);
SetContentView (Resource.Layout.Main);

Intent outsideIntent = Intent;
AlertDialog.Builder CodeAD = new AlertDialog.Builder (this);

CodeAD.SetTitle (“Superduperapp”);
CodeAD.SetMessage (“Code: ” + Intent.Data.EncodedAuthority);
CodeAD.Show ();

This is the result:

this is the screenshot of the Android app opened by the custom URL scheme

the Android app opened by our custom URL

Please note four things:

1 – in Xamarin Android, it is better to keep solution, project and class name in lowercase. I have had lots of issues when this wasn’t the case and I’m not entirely sure I was typing the names wrong. I think something may work incorrectly when you use class names LiKe_tHiS.

2 – the application name does NOT have to be the same of the URL scheme. You can register your app “uncommonApp” to deal with any URL: BeautifulThings://, http:// (if you’re making a browser), whatever://

3 – you don’t have to run the app to register the new association. Installation is enough.

4 – the URL association won’t work if you type the URL in a browser. It has to be a link in a web page or in an email.

A simple redirection mechanism using MVC 5 [and IIS8], including “Legacy” URLs

For some hours, I have been looking for good ideas on how to manage redirections in MVC without necessarily configuring IIS (which is not always available to the programmer, unfortunately).

However, very few of the walkthroughs found on the web take into account dealing with “legacy” URLs; primarily, those who have the “.html” extension.

How do I, in MVC, redirect a URL like “oldfolder/oldfilename.html” to a new MVC URL as “/newfolder/beautifulpeople” ?

The answer is not the simplest, because MVC doesn’t manage all that is asked to it by the browser:

A client request is handled, summarily, like this:

– MVC manages the “MVC” routes (as “/area/controller/action”)

– IIS8 manages the static files, which *presumably* don’t need MVC’s intervention.

If we want to manage all the redirections via MVC, we have to tell MVC that it has to take care of BOTH MVC routes AND static files (unless, of course, the latter don’t exist as such. If the static file exists, let IIS transfer it to the user).

The following is a very basic mechanism which uses MVC and a DB table to store redirections. It can be extended to use caching and OR XML files to be faster. It is also true that redirections should be an exception rather than the norm.

The idea is:

– We create a DB table holding old URLs and corresponding new URLs, along with the code we want to use for the redirection (301 is permanent) and an “active” flag.

– We create a set of MVC “catchall” routes (in the RouteConfig file) which will prevent 404 (“not found”) and will call a new controller that does the “redirection” job

– This new controller checks if the DB has an entry equal to the originating URL. If there is, it redirects  the flow to the new URL (permanenty or temporarily, depending on what we wrote in the DB entry); otherwise, it generates a custom 404 page.

– We tell MVC (in web.config) that it has to also take care of the routes that look like files, unless (of course) they are actual static files.


In our MVC application’s RouteConfig, we create, AFTER the standard routes, a set of “catchall” routes which will direct to a new controller and action (“Error”/”NotFound”) all the requests that could not be routed to an existing controller.

Like this:

//Default, Real route


name: “Default”,
url: “{controller}/{action}/{id}”,
defaults: new { controller = “Home”, action = “Index”, id = UrlParameter.Optional },
constraints: new { controller=”Home|Search|Account|Show|Other_Controllers|Error”} // CONSTRAINTS are VERY IMPORTANT

//catchAll routes to grab the URLs we want to redirect

name: “Redirect_OrError”,
url: “{*CatchAll1*}”,
defaults: new { controller = “Error”, action = “NotFound” }

name: “Redirect_OrError_two_levels”,
url: “{CatchAll1*}/{CatchAll2*}”,
defaults: new { controller = “Error”, action = “NotFound” }

name: “Redirect_OrError_three_levels”,
url: “{CatchAll1*}/{CatchAll2*}/{CatchAll3*}”,
defaults: new { controller = “Error”, action = “NotFound” }
name: “Redirect_OrError_four_levels”,
url: “{CatchAll1*}/{CatchAll2*}/{CatchAll3*}/{CatchAll4*}”,
defaults: new { controller = “Error”, action = “NotFound” }

Attention: The “default, real” MapRoute method must be called with Constraints (Controller=”Home|…. all the controllers you have). If you don’t do so, MVC will not fall through to our “catchall” controllers. It will stop at the default and will give a “404”.

The “Error” Controller

The “Error” Controller does three things:

1. It checks if the request is actually found in the Redirections table as a URL we consider as “old”

2. If it is there, we redirect to the new URL (if 301, “RedirectPermanent”; if others, “Redirect”)

3. If it doesn’t, it generates a custom error page with a 404 status code

public class ErrorController:Controller

public ActionResult NotFound()

string UrlToTest = Request.Url.AbsolutePath.Trim(‘/’);
Redirections redirect = RedirectManager.GetRedirectFromDB(UrlToTest);
if (redirect != null)
if (redirect.RedirectType==”301″)
return RedirectPermanent(redirect.NewURL);
return Redirect(redirect.NewURL);
Response.StatusCode = 404;
ViewBag.UrlToTest = UrlToTest;
return View();

public ErrorController()



Now what is the RedirectManager we just found in the code?

Very simply, it is a class which contains some helper classes and methods that allow us to examine the DB and look for the URL we want to redirect from.

public class RedirectManager


public RedirectManager()



public class RedirectionsDTO

public int Id { get; set; }
public string OldURL { get; set; }
public string NewURL { get; set; }
public string RedirectType { get; set; }
public Nullable<bool> Active { get; set; }


public static Redirections GetRedirectFromDB(string OldUrl)
RedirectionsDTO redirects;
using (var db = new OurEntitiesDB()) // this is the name of your Entity Framework
string URLWithoutSlash = OldUrl;
if (!URLWithoutSlash.StartsWith(“/”))
URLWithoutSlash = “/” + URLWithoutSlash;

redirects = (from e in db.Redirections
where (e.Active == true && (e.OldURL == URLWithoutSlash))
select new RedirectionsDTO
OldURL = e.OldURL,
NewURL = e.NewURL,
if (redirects != null)
return new Redirections { OldURL = redirects.OldURL, NewURL = redirects.NewURL, Active=redirects.Active, RedirectType=redirects.RedirectType };
return null;





How is the Redirect table created? It is created by Entity Framework Database first, based on a table maybe similar to this…

MVC redirection storage table

Table which holds redirection data

There should be an index on the OldURL column because we will include it in our queries.

The generated code could be something like this:

namespace YourPreferredNameSpace

using System;
using System.Collections.Generic;

public partial class Redirections
public int Id { get; set; }
public string OldURL { get; set; }
public string NewURL { get; set; }
public string RedirectType { get; set; }
public Nullable<bool> Active { get; set; }

Of course, you have to fill this table with the needed redirections! I suggest you create a controller and allow scaffolding templates to automatically generate the CRUD actions and views for these “Redirections” objects.


What we did so far does not help us if we want to redirect *.html files (or *.pdf files, for that matter). This is beacuse IIS will think that the *.html file should not be a part of an MVC route and it will look for it as a static file. To allow MVC to see the *.html URL as a possible MVC route (and redirect it, if needed), we have to allow MVC to examine all the file requests. To do so, we have three suggested paths. There are: an easy+smart way, a smart way and a semi-silly way. The easy+smart way didn’t work for me. The “smart way” did. It happens.

The easy+smart way is to patch the IIS as this article suggests:

It didn’t work for me because I had no access to IIS.

The “smart one” is suggested by Colin Farr in this old but powerful article:

he suggests that in System.webServers you add

<modules >
<remove name=”UrlRoutingModule-4.0″ />
<add name=”UrlRoutingModule-4.0″ type=”System.Web.Routing.UrlRoutingModule” preCondition=”” />

… other modules…


Now the silly solution instead:

add the runAllManagedModulesForAllRequests=”true” attribute to the “module” section. Colin Farr already explains why this is silly, so I will not.

<modules runAllManagedModulesForAllRequests=”true”>

Using Google and LinkedIn Accounts for Your .net MVC 5 Site’s Authentication: Tips and Tricks and the error externalLoginCallback?error=access_denied

Some months ago, Rick Anderson and Erik Reitan wrote a very good article in the website (  to show how the ASP.NET Identity authentication / authorization framework can leverage external authentication providers as Google, Facebook, Twitter and LinkedIn.

These providers do frequent changes to their interfaces. I am writing this post to underline a couple of tricky errors that the Google / LinkedIn authentications can present to you even if you seemingly do everything by the books.

Authentication with Google: tricks

Google can give you: “externalLoginCallback?error=access_denied” if you don’t allow your application to use certain – not so intuituive – APIs. In particular, the API that must be checked so that Google gives the green light for authentication is the Google+ API, which is not pre-authorized.

This is documented in MSDN:, however, i thought it was a good idea to replicate the same concept on this site in order to make it easier to find it with a search on the redirect URI error.

Another error one can get for the Google authentication is that the Google “project” has to have a PRODUCT_NAME (however, this is easy to spot because it is Google’s page itself to tell you where the problem lies).

All in all, these are the steps to enable the Google + authentication in MVC 5 (highly suggested to use Visual Studio 2013 Release 2 or superior)

Steps in Visual Studio

Create a new MVC project with “Individual user” authentication

From Nuget, download the Microsoft.Owin.Security.Google package

Google authentication package in NuGet

Google authentication package in NuGet

Enable https for your site (project – properties – set SSL enabled to true)

Copy the location of the SSL site (https://localhost:port_number/, for instance: https://localhost:44302/)

Steps in Google Developer Console

Go to Click on “Create Project”.

Click on the project name, click on APIs in the left menu and select “Google+ API”. Set it to ON (default is OFF)

Screenshot of the Google+ API we have to check to authenticate users in an MVC project

The Google+ API to enable if you want external authentication to work

Click on “Credentials” – oAuth.

Set the “Authorized Javascript origins” to the localhost SSL root (https://localhost:your_port_number). Set the “authorized redirect URLs” to localhost SSL root + /signin-google: for instance, https://localhost:43202/signin-google. No slash at the end of the URL!

Once you do this step, you have a ClientID and a Secret. You will need those for the Visual Studio application.

Configuring the ClientID in Google

Configuring the ClientID in Google

In the Consent screen, choose a contact email and give the PRODUCT a name!

Google Authentication: Consent screen

Google Authentication: Consent screen

Back to Visual Studio

In the folder App_Start, there is a file Startup.Auth.cs. 

Un-comment the lines releted to the Google authentication and fill the ClientId and ClientSecret fields with those given out by Google (these below are examples, they don’t work.

app.UseGoogleAuthentication(new GoogleOAuth2AuthenticationOptions()
ClientId = “”,
ClientSecret = “Uhjhkjhk189r_iGAsMZdHz”

Now you should be good to use Google to register and authenticate your users.


Authentication with LinkedIn: tricks

Rick and Erik mention this good tutorial for authentication with Yahoo and LinkedIn (+ a set of other OAuth 2.0 providers)

The LinkedIn tutorial is a bit simplified: it does not take into consideration the Redirection URI for localhost.

How to work with Localhost?

As with Google, you need to write down the httpS address of your localhost, for instance: https://localhost:44302/

Beware: for the authentication to work, the OAuth 2.0 redirection URLs must be set to https://localhost:44302/signin-linkedin (or your port of course). 

You have to set this address here:


In case you don’t append /signin-linkedin, you’ll end up with an “invalid redirect_uri” error:


URL routing in Microsoft MVC 5 when Areas are present: potential pitfalls

The “convention over configuration” philosophy of Microsoft’s MVC engine is very useful, as it automates a lot of “wiring” among the different components of a web application.

However, when the “going gets tough”, you have be careful how to circumvent certain convention-based automations that may bring undesired results.

One very important aspect to consider is routing, which technically is not part of MVC (it is a separate component of .net, as you can also use it with web forms) but plays an incredibly important role in the functioning of MVC. Routing is the mechanism that calls a certain object (in MVC, it is usually a controller) based on the URL the user typed or clicked on.

In MVC’s views based on Razor 3, we have a very user HTML helper which creates a URL based on:

– the controller we need

– the action we need.

Its syntax is the following:

@Html.ActionLink(“link text”, “action name”, “controller name”)

When you divide the application in Areas, you have to be extra-careful, as the overload that allows you to specify the Area you need has five arguments rather than four as you might wonder (since the Area is the fourth argument.)

So, in case you need a link that should call a controller inside an Area, it should read:

@Html.ActionLink(“link text”, “action name”, “controller name”, new {Area=”Area Name”}, new {})

The last new{} parameter is in lieu of html attributes. Without that specification, the compiler will think we’re calling the four-parameter overload, which has as fourth parameter… exactly the html attributes, not the Routing object and we would be wrong.

Is that all? No. There is another consideration related to the priority that the routing mechanism uses when you register more than one route in an Area route registration class (or any registration class, for that matter.)

When you create an area, in fact, an additional route AreaRegistration subclass is created for you.

For instance: if you create an area called “Particularities”, Visual Studio will create a class with this code (could not reproduce the indentation correctly here):
using System.Web.Mvc;
namespace RMTestSite.Areas.Particularities
public class ParticularitiesAreaRegistration : AreaRegistration
public override string AreaName
  return "Particularities";
public override void RegisterArea(AreaRegistrationContext context)
   new { action = "Index", id = UrlParameter.Optional }

So, if you want to point to the new Area controller from a page called by a controller that is in another Area, you would have to code:

@Html.ActionLink("Particularities","Index", "Home", new{Area="Particularities"}, new {})

The result of this link is an reference to:
http://localhost:53869/Particularities/Home, which is OK.

Now let us imagine we add another route to the Particularities Area.

For instance, let us add this route before our default route (as a rule, specialized routes should precede general routing rules):

new { action = "Index", id = UrlParameter.Optional }

What happens now if I use again my Html.ActionLink? I mean: if I use exactly again,
@Html.ActionLink("Particularities","Index", "Home", new{Area="Particularities"}, new {})

The result is different. The address becomes

Why is this? Because the routing mechanism found the first (in terms of: how the code is ordered) pattern in the route series which is matched by our controller/action ActionLink request. It does not choose the “simplest” one.

How can we continue to point to the previous controller/page?

We can specify the route itself when we build our link.

We can do this very easily by using RouteLink rather than the ActionLink. Some say this is in general a preferred routing habit: you can have thusly a list of what routes should do regardless where you want to implement the controllers and you are safer (well, in this case we would have been safe.)

Following our example, our code should have been
@Html.RouteLink("Particularities!", "Particularities_default", new { controller = "home", action = "index" }, new { })

We added the route name to the link, rather than the Area name, and we know we won’t get the wrong controller.

All in all, MVC’s routing mechanism (I specify, again, that is not a part of MVC per se) is a great thing, but we never have to give for granted that it will work in the way we guess a convention should work: it is the .net framework developer’s convention, not necessarily the one we think it is.

Xamarin.Forms: what about performance agains Xamarin.iOS “Classic”? Is it faster or slower?

As of the 1st of August, 2014, Xamarin issued the version 1.2.2 of the platform (version 1.2.1 proved really buggy. Luckily, the Xamarin guys patched it well).

I can now test how Xamarin Forms performs (in terms of speed) compared to a “classic” Xamarin iOS development.

I did a very similar test to the one we did on Android.

It is, in “Release” mode:

1. I create a scrollview for 50 times.

2. To every scrollview I add: 20 labels, 20 textfields with a placeholder, 20 buttons with an event handler.

3. all the labels, textfields and placeholders are removed from the scrollview and destroyed (except for the 100th iteration)

4. the scroll is removed from the root view (except for the 50th iteration)

Xamarin.iOS “Classic” (with iOS designer on visual studio, “release” configuration):

average of 3710 milliseconds on the iPhone 5 64 bit “simulator”

average of 14050 millseconds on the iPhone 5 “classic” device

Xamarin.Forms “Classic” (with iOS designer on visual studio): 

average of 141 milliseconds on the iPhone 5 64 bit “simulator”

average of 609 millseconds on the iPhone 5 “classic” device


So, in terms of how fast it is, on iOS Xamarin Forms beats Xamarin “classic” as it happens with Android, at least when it comes to standard UI buttons, labels and textfields.

This is the code:

“iOS Classic”

Code to test classic iOS development with Xamarin, in particular creation and destruction of subviews

Xamarin.iOS speed test code


Code to test performance of Xamarin Forms on iPhone and iPad

Xamarin.Forms test code