the “URL” DNS record that dnsimple made

Some time ago, in one of his Azure videos (generally given on a Friday), Scott Hanselman of MSFT showed a nice domain registrar / manager that works well with Azure websites: dnsimple.

To be honest, almost all registrars work well with Azure. However, dnsimple has a “semi-graphical” UI that helps you add the particular DNS records needed for Azure websites (or Amazon’s, for that matter… or many other cloud services…). For those of us who don’t like typing outside of Visual Studio, semi-GUI is bliss.

dnsimple (www.dnsimple.com) are a small company, which grants quick support and which has some good, original ideas. I am not affiliated to them in any way. They’re not cheap, either in the good or bad meaning of the term. They give good service, but they are a bit more expensive than your average registrar.

One of their good ideas is the URL record for your DNS.

What is a URL record, in addition to being the subject of this post?

Suppose you have registered two domains for the same site. For instance: you have a .com site in addition to an .fr, .it, .de, .co.uk… what-have-you.

For example: one of my customers has the domain www.bvevents.com in addition to the domain www.bvevents.it. Both domains “serve” the same content. Everyone knows search engines do not like duplicate content.

You have basically three ways to avoid search engines think one site is “stealing” content from the other:

1. You fill your pages with the “canonical” metadata to advise search engines you’re not spawning the oceans with the same content in different sites (“canonical” indicates what page is the “original”)

2. You ask your web server to rewrite the URL to only one of the sites; for instance: what does not match ^www\.yoursite\.com$ >>> rewrites to http://www.yoursite.com/{R:1}

3. You use dnsimple’s “URL” “special” records.

dnsimple URL records

dnsimple URL records

A URL record redirects a domain to another with a 301 code you don’t have to set up in your server: dnsimple does it for you.

In our case: we wanted all the “.it” content to be served by the “.com” domain, so we set up a URL entry that redirects all .it pages to the corresponding .com pages. See in the image below what Chrome registers for our .it request.

dnsimple URL records

Automatic redirection with dnsimple URL records

This is an idea that saves you some duplicate content hassles.

Controller versus view in MVC .net: is the code in the view as fast as that in the controller? Is it slower?

One of the basic rules of MVC is that views should be only – exactly – views, that is to say: objects that present to the user something that is already “worked and calculated”.

They should perform little, if not none at all, calculation. All the significant code should be in the controllers. This allows better testability and maintainability.

Is this, in Microsoft’s interpretation of MVC, also justified by performance?

We tested this with a very simple code that does this:

– creates 200000 “cat” objects and adds them to a List

– creates 200000 “owner” objects and adds them to a List

– creates 200000 “catowner” objects (the MTM relation among cats and owners) and adds them to a List

– navigates through each cat, finds his/her owner, removes the owner from the list of owners (we don’t know if cats really wanted this, but their freedom on code fits our purposes).

We’ve run this code in a controller and in a razor view.

The result seem to suggest that the code in views runs just as fast as in controllers even if don’t pre-compile views (the compilation time in our test is negligible).

The average result for the code with the logic in the controller is 18.261 seconds.

The average result for the code with the logic in the view is 18.621 seconds.

The performance seems therefore very similar.

Here is how we got to this result.

Case 1: Calculations are in the CONTROLLER

Models:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace WebPageTest.Models
{
public class Owner
{
public string Name { get; set; }
public DateTime DOB { get; set; }
public virtual CatOwner CatOwner { get; set; }
}
public class Cat
{
public string Name { get; set; }
public DateTime DOB { get; set; }
public virtual CatOwner CatOwner { get; set; }
}
public class CatOwner
{
public virtual Cat Cat { get; set; }
public virtual Owner Owner { get; set; }
}
}

Controller:

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using WebPageTest.Models;

namespace WebPageTest.Controllers
{
public class HomeController : Controller
{
public ActionResult Index()
{
Stopwatch howLongWillItTake = new Stopwatch();
howLongWillItTake.Start();
List<Owner> allOwners = new List<Owner>();
List<Cat> allCats = new List<Cat>();
List<CatOwner> allCatOwners = new List<CatOwner>();
// create lists with 200000 cats, 200000 owners, 200000 relations
for (int i = 0; i < 200000; i++)
{
//Cat
Cat CatX = new Cat();
CatX.Name = “Cat ” + i.ToString();
CatX.DOB = DateTime.Now.AddDays(i / 10);
//Owner
Owner OwnerX = new Owner();
OwnerX.Name = “Owner ” + i.ToString();
OwnerX.DOB = DateTime.Now.AddDays(-i / 10);
//Relationship “table”
CatOwner CatOwnerXX = new CatOwner();
CatOwnerXX.Cat = CatX;
// Relations
CatOwnerXX.Owner = OwnerX;
CatX.CatOwner = CatOwnerXX;
OwnerX.CatOwner = CatOwnerXX;
//add to list
allCats.Add(CatX);
allOwners.Add(OwnerX);
allCatOwners.Add(CatOwnerXX);
}
// now I remove all the items
foreach (Cat CatToDelete in allCats)
{
Owner OwnerToRemove = CatToDelete.CatOwner.Owner;
allOwners.Remove(OwnerToRemove);
}
// now all cats are free
int numberOfCats = allCats.Count();
int numberOfOwners = allOwners.Count();
howLongWillItTake.Stop();
long elapsedTime = howLongWillItTake.ElapsedMilliseconds;
// give info to the view
ViewBag.numberOfCats = numberOfCats;
ViewBag.numberOfOwners = numberOfOwners;
ViewBag.elapsedTime = elapsedTime;
return View();
}
}
}

View:

<div class=”row”>
<div class=”col-md-12″>
<hr />
<b>Results</b>
<br/>
Cats: @ViewBag.numberOfCats
<br/>
Owners: @ViewBag.numberOfOwners
<br/>
ElapsedTime in milliseconds: @ViewBag.ElapsedTime
<hr />
</div>
</div>

Case 2: Calculations are in the VIEW (pre-compiled)

Models: same as above

Controller:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace WebPageTest.Controllers
{
public class HomeBisController : Controller
{
public ActionResult Index()
{
return View();
}
}
}

View:

@using System;
@using System.Collections.Generic;
@using System.Diagnostics;
@using System.Linq;
@using System.Web;
@using WebPageTest.Models;
@using System.Web.Mvc;
@{
Stopwatch howLongWillItTake = new Stopwatch();
howLongWillItTake.Start();
List<Owner> allOwners = new List<Owner>();
List<Cat> allCats = new List<Cat>();
List<CatOwner> allCatOwners = new List<CatOwner>();
//create lists with 200000 cats, 200000 owners, 200000 relations
for (int i = 0; i < 200000; i++)
{
//Cat
Cat CatX = new Cat();
CatX.Name = “Cat ” + i.ToString();
CatX.DOB = DateTime.Now.AddDays(i / 10);
//Owner
Owner OwnerX = new Owner();
OwnerX.Name = “Owner ” + i.ToString();
OwnerX.DOB = DateTime.Now.AddDays(-i / 10);
//Relationship “table”
CatOwner CatOwnerXX = new CatOwner();
CatOwnerXX.Cat = CatX;
// Relations
CatOwnerXX.Owner = OwnerX;
CatX.CatOwner = CatOwnerXX;
OwnerX.CatOwner = CatOwnerXX;
//add to list
allCats.Add(CatX);
allOwners.Add(OwnerX);
allCatOwners.Add(CatOwnerXX);
}
// now I remove all the items
foreach (Cat CatToDelete in allCats)
{
Owner OwnerToRemove = CatToDelete.CatOwner.Owner;
allOwners.Remove(OwnerToRemove);
}
// now all cats are free
int numberOfCats = allCats.Count();
int numberOfOwners = allOwners.Count();
howLongWillItTake.Stop();
long elapsedTime = howLongWillItTake.ElapsedMilliseconds;
// give info to the view

}
<div class=”row”>
<div class=”col-md-12″>
<hr />
<b>Results</b>
<br />
Cats: @numberOfCats
<br />
Owners: @numberOfOwners
<br />
ElapsedTime in milliseconds: @elapsedTime
<hr />
</div>
</div>

How fast is classic ADO.net compared to Entity Framework?

Or maybe I should write: how slower is Entity Framework as compared to ADO.Net?

By Entity Framework I mean Microsoft’s open source package that allows you to manage DB objects via strongly-typed classes and collections.

By ADO.Net I mean peeking into the DB using the old ADO objects SQLConnection, SQLCommand, SQLParameters

This is the little test (note that it is a very peculiar test because rarely will you in real life insert, update and delete objects one by one: more massive operations are more likely):

– we create two table: Books and Authors. They are related via Author_Id, which is on the Books table.

– we insert 1000 authors and 1000 books

. we update 1000 books with a new title (one by one)

– we delete 1000 books (one by one)

– DB Is SQLserver version 11, running on a quad-core i5 @1.9 Ghz running Windows 8

– Server is a Windows 8 machine with 8Gb Gb RAM

The code for Entity Framework?

Book Model

namespace FastEF.Models
{
 public class Book
 {
 public int Id { get; set; }
 public string Title { get; set; }
 public Author Author { get; set; }
 
 }
}

Author Model

namespace FastEF.Models
{
 public class Author
 {
 public int Id { get; set; }
 public string Name { get; set; }
 public string Address { get; set; }
 public ICollection<Book> Books { get; set; }
}
}

DbContext

namespace FastEF.Models
{
 public class DBCreator:DbContext
 {
 public DbSet<Book> Books { get; set; }
 public DbSet<Author> Authors { get; set; }
}
}

Then, the action from Entity Framework test, which:

– inserts 1000 auhors and 1000 books related to the authors

– updates the 1000 books

– deletes the 1000 books


 public ActionResult EF()
        {
            Book bookToCreate = new Book();
            Author authorToCreate = new Author();
            Stopwatch tellTime = new Stopwatch();
            long insertingTime = 0;
            long updatingTime = 0;
            long deletingTime = 0;
            List generatedBookIds = new List();

            // let us delete table contents
            try
            {
                var objCtx = ((System.Data.Entity.Infrastructure.IObjectContextAdapter)thisDB).ObjectContext;
                objCtx.ExecuteStoreCommand("DELETE FROM Books");
                objCtx.ExecuteStoreCommand("DELETE FROM Authors");

            }


            catch (Exception e)
            {
                // write exception. Maybe it's the first time we run this and have no tables
                Debug.Write("Error in truncating tables: {0}", e.Message);

            }

            // let us start the watch
            tellTime.Start();

            // INSERTING!
            // we create 1000 authors with name="John Doe nr: " + a GUID
            // and address ="5th Avenue nr: " + a GUID
            // we create a book called "The Cronicles of: " + a GUID and attach it to the author
            // we save the book, so the author is also automatically created

            for (int i = 0; i < 1000; i++)
            {

                // creating author
                authorToCreate = new Author();
                authorToCreate.Name = "John Doe nr. " + Guid.NewGuid();
                authorToCreate.Address = "5th Avenue nr. " + Guid.NewGuid();

                //creating book and linking it to the author
                bookToCreate = new Book();
                bookToCreate.Title = "The Chronicles of: " + Guid.NewGuid();
                bookToCreate.Author = authorToCreate;

                //saving the book. Automatically, the author is saved
                thisDB.Books.Add(bookToCreate);
                thisDB.SaveChanges();
                generatedBookIds.Add(bookToCreate.Id);
            }

            insertingTime = tellTime.ElapsedMilliseconds; // how did I do with inserting?

            tellTime.Restart(); // restart timer

            // We update the 1000 books by changing their title
            foreach (int bookId in generatedBookIds)
            {

                Book bookToUpdate = thisDB.Books.Find(bookId);
                bookToUpdate.Title = "New chronicles of: " + Guid.NewGuid();

                thisDB.SaveChanges();

            }

            updatingTime = tellTime.ElapsedMilliseconds; // how did I do with inserting?
            tellTime.Restart(); // restart timer

            // We delete 1000 books, one by one
            foreach (int bookId in generatedBookIds)
            {

                Book bookToDelete = thisDB.Books.Find(bookId);
                thisDB.Books.Remove(bookToDelete);

            }

            deletingTime = tellTime.ElapsedMilliseconds; // how did I do with inserting?
            tellTime.Stop(); // stop timer


            //printing the results 

            string returnedMessage = "Results with Entity Framwork 6.1: ";
            returnedMessage += "
1000 Insert operations in ms.: " + insertingTime.ToString(); returnedMessage += "
1000 Update operations in ms.: " + updatingTime.ToString(); returnedMessage += "
1000 Delete operations in ms.: " + deletingTime.ToString(); return Content(returnedMessage); }

The code for ADO.Net?

 public ActionResult SQLClient()
        {

            string insertAuthorSQL = "INSERT INTO Authors (Name, Address) VALUES (@name, @address)";
            string insertBookSQL = "INSERT INTO Books(Title, Author_Id) VALUES (@Title, @Author_Id)";
            string updateBookSQL = "UPDATE Books Set Title=@Title where Id=@Id";
            string deleteBookSQL = "DELETE Books where Id=@Id";

            Book bookToCreate = new Book();
            Author authorToCreate = new Author();
            Stopwatch tellTime = new Stopwatch();

            // SQL Objects we will use
            SqlConnection connAntiEF = new SqlConnection(WebConfigurationManager.ConnectionStrings["DefaultConnection"].ToString());
            SqlCommand cmdAntiEF = new SqlCommand();

            // Open Connection
            connAntiEF.Open();

            long insertingTime = 0;
            long updatingTime = 0;
            long deletingTime = 0;
            List generatedBookIds = new List();

            // let us delete table contents
            try
            {
                cmdAntiEF = new SqlCommand("DELETE FROM Books", connAntiEF);
                cmdAntiEF.ExecuteNonQuery();
                cmdAntiEF = new SqlCommand("DELETE FROM Authors", connAntiEF);
                cmdAntiEF.ExecuteNonQuery();
            }


            catch (Exception e)
            {
                // write exception. 
                Debug.Write("Error in truncating tables: {0}", e.Message);

            }

            // let us start the watch
            tellTime.Start();

            // INSERTING!
            // we create 1000 authors with name="John Doe nr: " + a GUID
            // and address ="5th Avenue nr: " + a GUID
            // we create a book called "The Cronicles of: " + a GUID and attach it to the author
            // we save the book, so the author is also automatically created

            for (int i = 0; i < 1000; i++)
            {

                // creating author
                authorToCreate = new Author();
                authorToCreate.Name = "John Doe nr. " + Guid.NewGuid();
                authorToCreate.Address = "5th Avenue nr. " + Guid.NewGuid();

                //creating book and linking it to the author
                bookToCreate = new Book();
                bookToCreate.Title = "The Chronicles of: " + Guid.NewGuid();
                bookToCreate.Author = authorToCreate;

                // INSERT book with SQL and get its Id


                SqlParameter parmName = new SqlParameter("Name", authorToCreate.Name);
                SqlParameter parmAddress = new SqlParameter("Address", authorToCreate.Address);
                cmdAntiEF.CommandText = insertAuthorSQL;
                cmdAntiEF.Parameters.Add(parmName);
                cmdAntiEF.Parameters.Add(parmAddress);
                cmdAntiEF.ExecuteNonQuery();

                cmdAntiEF.Parameters.Clear();
                cmdAntiEF.CommandText = "SELECT @@IDENTITY";

                int insertedAuthorID = Convert.ToInt32(cmdAntiEF.ExecuteScalar());

                // INSERT book with SQL and get its Id


                parmName = new SqlParameter("title", bookToCreate.Title);
                parmAddress = new SqlParameter("author_id", insertedAuthorID);

                cmdAntiEF.CommandText = insertBookSQL;
                cmdAntiEF.Parameters.Add(parmName);
                cmdAntiEF.Parameters.Add(parmAddress);
                cmdAntiEF.ExecuteNonQuery();

                // we neeed the book's Id to iterate through the Id's later
                cmdAntiEF.CommandText = "SELECT @@IDENTITY";
                int insertedBookID = Convert.ToInt32(cmdAntiEF.ExecuteScalar());
                generatedBookIds.Add(insertedBookID);


                parmName = null;
                parmAddress = null;
                cmdAntiEF.Parameters.Clear();

            }


            insertingTime = tellTime.ElapsedMilliseconds; // how did I do with inserting?

            tellTime.Restart(); // restart timer

            // We update 1000 books by changing their title
            cmdAntiEF.CommandText = updateBookSQL;
            foreach (int bookId in generatedBookIds)
            {

                //parameters are loaded with the book's new data
                SqlParameter parmTitle = new SqlParameter("Title", "New chronicles of: " + Guid.NewGuid());
                SqlParameter parmId = new SqlParameter("Id", bookId);
                cmdAntiEF.Parameters.Add(parmTitle);
                cmdAntiEF.Parameters.Add(parmId);

                cmdAntiEF.ExecuteNonQuery();
                parmTitle = null;
                cmdAntiEF.Parameters.Clear();

            }

            updatingTime = tellTime.ElapsedMilliseconds; // how did I do with inserting?
            tellTime.Restart(); // restart timer

            // We delete 1000 books one by one
            cmdAntiEF.CommandText = deleteBookSQL;
            foreach (int bookId in generatedBookIds)
            {
                SqlParameter parmId = new SqlParameter("Id", bookId);
                cmdAntiEF.Parameters.Add(parmId);
                cmdAntiEF.ExecuteNonQuery();
                parmId = null;
                cmdAntiEF.Parameters.Clear();
            }

            connAntiEF.Close();

            deletingTime = tellTime.ElapsedMilliseconds; // how did I do with inserting?
            tellTime.Stop(); // stop timer

            // printing the results
            string returnedMessage = "Results with SQL Connection: ";
            returnedMessage += "
1000 Insert operations in ms.: " + insertingTime.ToString(); returnedMessage += "
1000 Update operations in ms.: " + updatingTime.ToString(); returnedMessage += "
1000 Delete operations in ms.: " + deletingTime.ToString(); return Content(returnedMessage); }

How did they do?

Entity Framework

Results with Entity Framwork 6.1:
1000 Insert operations in ms.: 11355
1000 Update operations in ms.: 20833
1000 Delete operations in ms.: 18117

Entity framework performance

Adding, updating, deleting 1000 sqlserver objects via EF

CPU average use: 35%

Memory average use: 65%

ADO.Net

Results with SQL Connection:
1000 Insert operations in ms.: 921
1000 Update operations in ms.: 309
1000 Delete operations in ms.: 311

ado.net insert and update and delete

Inserting, updating, deleting sql server objects via ado

How to interpret the results?

They cannot be compared, because using EF means using objects rather than non-typed records.

So, I keep on thinking ORMs are the way to go.

However, if one day I was asked to speed up parts of an application that is slow when reading / writing data, I would know where to go and look for possible ameliorations.

Entity Framework: Database first or code first? Some non-conceptual, very practical differences in real life scenarios

In the last years, Microsoft has promoted Code First as a very comfortable way to make your web (or even client-server) application communicate with your database (I am not talking only about Sql Server. I have had good experience of Entity Framework with Oracle databases as well).

Code First, in contrast with Database first.

Database first is how it has always worked in the IT world:

  1. first you create a DB
  2. then you create objects in your application that are a representation of your DB, and modify the DB contents through the objects.

Code First works the other way around:

  1. first you create (business?) classes in your application
  2. then Entity framework creates the DB tables to hold those objects and keep track of the DB modifications.

There is a third approach (Model First), but I have never really given it a chance because the other two were really sufficient for what I do.

What is better? the Practical Approach

Let us see how the DB-classes link is created in Database First and how this changes in Code First.

The problem:

I am a tie salesperson. I have two entities that are linked:

  1. ties
  2. racks

A tie can be linked to one rack. Racks can hold many ties.

Managing Related Tables in Entity Framework Database First

These are my Racks

CREATE TABLE [dbo].[Rack] (
[Id] INT NOT NULL IDENTITY,
[RackPosition] NVARCHAR (MAX) NULL,
PRIMARY KEY CLUSTERED ([Id] ASC)
);

These are my Ties (linked to my Racks via the RackId, that is a foreign key)

CREATE TABLE [dbo].[Tie] (
[Id] INT IDENTITY (1, 1) NOT NULL,
[TieSerial] INT NULL,
[RackId] INT NOT NULL,
PRIMARY KEY CLUSTERED ([Id] ASC)
);

ALTER TABLE [dbo].[Tie] WITH CHECK ADD CONSTRAINT [FK_Tie_Rack] FOREIGN KEY([RackId])
REFERENCES [dbo].[Rack] ([Id])
GO

These are the tables as you see them in Sql Management Studio:

Image of the two DB tables

The two tables created in the DB

In order to create the classes out of this Database, in Visual Studio we:

  1. Add or update the entity framework package to our web project (why not via NuGet, and why not 6.1, at the beginning of November 2014?)
  2. Add the ADO.NET Entity object to our project (we choose the option “EF Designer from DB”)
  3. We specify the connection string and finally import the DB objects

In Sql Management studio, we add some data to the Rack table, so that – when we create new ties – they can be hung on something!

Racks in the Rack table, Database first

Let us add some racks

Database first: choose what tables you want to import

DB Object to import in database first

We build the solution. At the end, the EF scripts create these class files we take good care of, because we will reuse them in Code First approach:

namespace DatabaseFirst
{
using System;
using System.Collections.Generic;

public partial class Tie
{
public int Id { get; set; }
public Nullable<int> TieSerial { get; set; }
public int RackId { get; set; }

public virtual Rack Rack { get; set; }
}
}

and

namespace DatabaseFirst
{
using System;
using System.Collections.Generic;

public partial class Rack
{
public Rack()
{
this.Ties = new HashSet<Tie>();
}

public int Id { get; set; }
public string RackPosition { get; set; }

public virtual ICollection<Tie> Ties { get; set; }
}
}

Please note: since the foreign key is on the Tie, this means a Tie has a Rack. A Rack has multiple Ties (thus, the ICollection of Ties) in the Rack object

Now, let us see what happens when we create an MVC controller and “scaffold” views

Let us create the views to edit these objects

MVC scaffolding of Database first objects

Below, the code we get for the Ties Controller. Note the bold statements: the scaffolding templates have recognized that, when we create or show a Tie, we also create or show the Rack it is bound to.

Note also that the templates makes use of the RackId field to create and modify the link between the Tie and the Rack.

public class TiesController : Controller
{
private DatabaseFirstDBEntities db = new DatabaseFirstDBEntities();

// GET: Ties
public ActionResult Index()
{
var ties = db.Ties.Include(t => t.Rack);
return View(ties.ToList());
}

// GET: Ties/Details/5
public ActionResult Details(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Tie tie = db.Ties.Find(id);
if (tie == null)
{
return HttpNotFound();
}
return View(tie);
}

// GET: Ties/Create
public ActionResult Create()
{
ViewBag.RackId = new SelectList(db.Racks, “Id”, “RackPosition”);
return View();
}

// POST: Ties/Create
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = “Id,TieSerial,RackId”)] Tie tie)
{
if (ModelState.IsValid)
{
db.Ties.Add(tie);
db.SaveChanges();
return RedirectToAction(“Index”);
}

ViewBag.RackId = new SelectList(db.Racks, “Id”, “RackPosition”, tie.RackId);
return View(tie);
}

// GET: Ties/Edit/5
public ActionResult Edit(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Tie tie = db.Ties.Find(id);
if (tie == null)
{
return HttpNotFound();
}
ViewBag.RackId = new SelectList(db.Racks, “Id”, “RackPosition”, tie.RackId);
return View(tie);
}

// POST: Ties/Edit/5
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit([Bind(Include = “Id,TieSerial,RackId”)] Tie tie)
{
if (ModelState.IsValid)
{
db.Entry(tie).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction(“Index”);
}
ViewBag.RackId = new SelectList(db.Racks, “Id”, “RackPosition”, tie.RackId);
return View(tie);
}

// GET: Ties/Delete/5
public ActionResult Delete(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Tie tie = db.Ties.Find(id);
if (tie == null)
{
return HttpNotFound();
}
return View(tie);
}

// POST: Ties/Delete/5
[HttpPost, ActionName(“Delete”)]
[ValidateAntiForgeryToken]
public ActionResult DeleteConfirmed(int id)
{
Tie tie = db.Ties.Find(id);
db.Ties.Remove(tie);
db.SaveChanges();
return RedirectToAction(“Index”);
}

protected override void Dispose(bool disposing)
{
if (disposing)
{
db.Dispose();
}
base.Dispose(disposing);
}
}

The scaffolding creates not only the controller, but also the views.

This is the Create view (you will notice the creation of a dropdown list that allows us to choose the rack the tie is hung on)

DB First: creation of a new record

Creation of a new record with Entity Framework DB first

And last the index page, which shows what we just created

Tie Table in database first

The ties in our table

Noteworthy:

When the model is sent from the view to the controller, the rack object that is linked to the tie is null (see the breakpoint screenshot). However, the RackId key is not. This allows the DB to keep the link between the new tie and the chosen rack.

model of tie table entry

screenshot of the tie model

Managing Related Tables in Entity Framework Code First

To test how all of this works in the “Code First” world, I will do so:

Create a new Visual Studio project (web application, MVC)

  1. Upgrade EF to 6.1
  2. Prepare a new DB, called CodeFirst
  3. Create model classes from the same classes that were generated automatically by EF in Database First
  4. Add to the project an “Entity framework Code First” ADO.net object. This doesn’t do a lot: basically, it creates a new connection string for you [that you will have to change to make it point to your real DB].
  5. The ADO.net object also adds a DbContext class where you have to specify what classes will be written to the DB (this is another difference from Database First: naturally, Database first asks you where to read data from and what data it should read. Code First does not ask where it should write data and what it should write. You have to write additional code for that. But it’s not a lot.)

This is how the DbContext class looks like after our intervention. In bold, the code we added.

public class CodeFirstModel : DbContext
{
// Your context has been configured to use a ‘CodeFirstModel’ connection string from your application’s
// configuration file (App.config or Web.config). By default, this connection string targets the
// ‘CodeFirst.CodeFirstModel’ database on your LocalDb instance.
//
// If you wish to target a different database and/or database provider, modify the ‘CodeFirstModel’
// connection string in the application configuration file.
public CodeFirstModel()
: base(“name=DefaultConnection”)
{
}

// Add a DbSet for each entity type that you want to include in your model. For more information
// on configuring and using a Code First model, see http://go.microsoft.com/fwlink/?LinkId=390109.

// public virtual DbSet<MyEntity> MyEntities { get; set; }

public virtual DbSet<Tie> Ties { get; set; }
public virtual DbSet<Rack> Racks { get; set; }
}

Now, we ask the scaffolding engine to generate the controller exactly as we did with Database first

Code first in Entity framework: code creation

Code First Controller creation

The created controller is exactly like that of the Database first controller.

public class TiesController : Controller

{
private CodeFirstModel db = new CodeFirstModel();

// GET: Ties
public ActionResult Index()
{
var ties = db.Ties.Include(t => t.Rack);
return View(ties.ToList());
}

// GET: Ties/Details/5
public ActionResult Details(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Tie tie = db.Ties.Find(id);
if (tie == null)
{
return HttpNotFound();
}
return View(tie);
}

// GET: Ties/Create
public ActionResult Create()
{
ViewBag.RackId = new SelectList(db.Racks, “Id”, “RackPosition”);
return View();
}

// POST: Ties/Create
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = “Id,TieSerial,RackId”)] Tie tie)
{
if (ModelState.IsValid)
{
db.Ties.Add(tie);
db.SaveChanges();
return RedirectToAction(“Index”);
}

ViewBag.RackId = new SelectList(db.Racks, “Id”, “RackPosition”, tie.RackId);
return View(tie);
}

// GET: Ties/Edit/5
public ActionResult Edit(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Tie tie = db.Ties.Find(id);
if (tie == null)
{
return HttpNotFound();
}
ViewBag.RackId = new SelectList(db.Racks, “Id”, “RackPosition”, tie.RackId);
return View(tie);
}

// POST: Ties/Edit/5
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit([Bind(Include = “Id,TieSerial,RackId”)] Tie tie)
{
if (ModelState.IsValid)
{
db.Entry(tie).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction(“Index”);
}
ViewBag.RackId = new SelectList(db.Racks, “Id”, “RackPosition”, tie.RackId);
return View(tie);
}

// GET: Ties/Delete/5
public ActionResult Delete(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Tie tie = db.Ties.Find(id);
if (tie == null)
{
return HttpNotFound();
}
return View(tie);
}

// POST: Ties/Delete/5
[HttpPost, ActionName(“Delete”)]
[ValidateAntiForgeryToken]
public ActionResult DeleteConfirmed(int id)
{
Tie tie = db.Ties.Find(id);
db.Ties.Remove(tie);
db.SaveChanges();
return RedirectToAction(“Index”);
}

protected override void Dispose(bool disposing)
{
if (disposing)
{
db.Dispose();
}
base.Dispose(disposing);
}
}

The database is not created, yet.

To create it, either you enable Migrations (in Package console), or – more simply – you launch the application and, via the automatically generated views, create a DB entry that does not depend on other objects (you might as well seed some objects in the database via code, but we want to keep this example as simple as possible),

So, we create new Racks with a Racks controller (we do not start creating Ties because you cannot have a Tie without a Rack). The DB is automatically created. After we create some racks, we can add ties to them.

filling db items in code first

Create racks in Code first

Db created by code first approach

Codefirst database

How does the “automatic” DB look like? Well, it does look identical to the DB first approach: entity framework has indeed created two tables (with a plural name, but there is an option to specify it should remain singular) and the foreign keys.

Now we create our Ties

Tie table creation

We create Ties in CodeFirst now

We have obtained exactly the same result as with Database First.

Bottom line: what is better?

Rarely as in this occasion have I felt entitled to say: it’s the same, it depends on your inclinations and what you have at hand.

Database First is better if you have large databases you need your code to mirror (for smaller DBs, there is the opportunity to do Codefirst importing a part of the DB and creating the rest via .net classes)

Code First is better if you have an empty DB and don’t want to spend too much time switching between two different environments (the code IDE and the DB IDE).

With Code First, you have to learn some new attributes that you will use in your code to specify DB-related attributes as: a certain column has an index, a certain column should not go to the DB at all, and so on.

What do I prefer?

Lately I have gone with Code First because I have always been repaid by investments in technologies that automate certain processes even if at the beginning they seem to confront problems in a simplistic way.

Usually, these technologies improve and take away a lot of programming hassles. Take ORMs: how many developers would have bet they would almost totally replace field-level programming one day? Code First  gives you a more centralized view of your application, with potentially fewer bug to take care of in the future. That did the trick for me.

C# 5 polymorphism notes: interface implementations at subclass level

When we want to show how polymorphism works, we often use the superclass -> subclass example and verify how overridden methods of the subclass are dynamically invoked when the subclass is created using the superclass’s type (in this fashion: SuperClassType x = new SubClassType() )

Here I would like to show something a bit different: how dynamic invocation of methods works when we create objects using the type of an interface they implement, and what changes if the subclasses inherit from a superclass and implement the interface itself.

The interface and objects we’ll use are very simple.

We have an interface called IAreaOrVolume, which contains a “blueprint” method AreaOrVolumeSize.

We have a “Quad” class that implements this interface.

Quad gives back the Area by multiplying its own width by its own height.

Then, we have a PossibleSquare that subclasses Quad. We call it “PossibleSquare” because we will see that, given the inheritance mechanisms, at times it is a Square but works as a Quad.

We have a PossibleCube that subclasses PossibleSquare. We call it “PossibleCube” because it is a Cube BUT its volume is at times (we will see exactly when) calculated as a Square’s or even any Quad’s area. Probably the idea that a “Cube” is a subclass of a “Square” is logically flawed, as a Square is a “slice” of a Cube, but for the time let us forget about the Aristotelic Ideas and let us see just what they mean in C#.

All objects have a constructor that accepts width, height and depth. Even if a Square does not have a height different from its width, we pass the constructor a width different from the height to show how unexpected results can stem from different implementations of inheritance.

In this first example, the “AreaOrVolumeSize” method is declared as “virtual” in the superclass “Quad” and overridden in the subclasses. See, in bold, the modifiers “virtual” and “override”.

namespace TestInheritanceWithInterfaces
{

interface IAreaOrVolume
{
double AreaOrVolumeSize();
//whatever object implements this interface will have to define its own AreaOrVolumeSize metod
}

class Quad : IAreaOrVolume
{
protected double _width;
protected double _height;
protected double _depth;

public Quad(double width, double height, double depth)
{
_width = width;
_height = height;
_depth = depth;

}

public virtual double AreaOrVolumeSize() // virtual means: go on, you can override me
{
return _width * _height * 1;
// this is a Quad. In calculating “Area or Volume”, we disregard the depth of the object, as a Quad has an area, not a volume
}

}

class PossibleSquare : Quad
{
public PossibleSquare(double width, double height, double depth) : base(width, height, depth) { }

public override double AreaOrVolumeSize()
{
return _width * _width * 1;
// this is a Square. In calculating “Area or Volume”, we disregard the depth of the object,
// as a Square has an area, not a volume
// we also disregard the height as it is equal to the width
}
}

class PossibleCube : PossibleSquare
{
public PossibleCube(double width, double height, double depth) : base(width, height, depth) { }

public override double AreaOrVolumeSize()
{
return _width * _width * _width;
// this is a Cube.
// In calculating the volume, we disregard depth and height as they are both equal to the width
}
}

class Program
{
static void Main(string[] args)
{
IAreaOrVolume thisShape;
// typing our variable with the interface implemented by classes and subclasses allows
// polymorphism

thisShape = new Quad(5,6,1);
Debug.WriteLine(“Shape’s area or volume: {0}”,thisShape.AreaOrVolumeSize());

thisShape = new PossibleSquare(5,6,1);
Debug.WriteLine(“Shape’s area or volume: {0}”, thisShape.AreaOrVolumeSize());

thisShape = new PossibleCube (5,6,2);
Debug.WriteLine(“Shape’s area or volume: {0}”, thisShape.AreaOrVolumeSize());
}

}

}

The results are what we expected:

Quad’s area or volume: 30
Square’s area or volume: 25 (height is ignored in the overridden method; the area is a Square’s area = width squared)
Cubes’s area or volume: 125 (height is ignored in the overridden method; volume is the cube’s volume = width to the power of three)

What happens, instead, if we declare the AreaOrVolumeSize as “new” methods, which do not inherit from their superclass?

In this following example, the AreaOrVolumeSize method is not overridden, but marked as “new” suggesting that we want to hide the superclass’s method.

namespace TestInheritanceWithInterfaces
{

interface IAreaOrVolume
{
double AreaOrVolumeSize();
//whatever object implements this interface will have to define its own AreaOrVolumeSize metod
}

class Quad : IAreaOrVolume
{
protected double _width;
protected double _height;
protected double _depth;

public Quad(double width, double height, double depth)
{
_width = width;
_height = height;
_depth = depth;

}

public double AreaOrVolumeSize()
{
return _width * _height * 1;
// this is a Quad. We disregard the depth of the object, as a Quad has an area, not a volume
}

}

class PossibleSquare : Quad
{
public PossibleSquare(double width, double height, double depth) : base(width, height, depth) { }

public new double AreaOrVolumeSize() // new hides the superclass’s implementation
{
return _width * _width * 1;
// this is a Square. We disregard the depth of the object,
// as a Square has an area, not a volume
// we also disregard the height as it is equal to the width
}
}

class PossibleCube : PossibleSquare
{
public PossibleCube(double width, double height, double depth) : base(width, height, depth) { }

public new double AreaOrVolumeSize()
{
return _width * _width * _width;
// this is a Cube.
// we disregard depth and height as they are both equal to the width
}
}

class Program
{
static void Main(string[] args)
{
IAreaOrVolume thisShape;
// typing our variable with the interface implemented by classes and subclasses allows
// polymorphism

thisShape = new Quad(5,6,1);
Debug.WriteLine(“Quad’s area or volume: {0}”,thisShape.AreaOrVolumeSize());

thisShape = new PossibleSquare(5,6,1);
Debug.WriteLine(“Square’s area or volume: {0}”, thisShape.AreaOrVolumeSize());

thisShape = new PossibleCube (5,6,2);
Debug.WriteLine(“Cubes’s area or volume: {0}”, thisShape.AreaOrVolumeSize());
}
}
}

The result is what we expected, and a bit funny:

Quad’s area or volume: 30
Square’s area or volume: 30
Cubes’s area or volume: 30

What happened here is: since we declared the AreaOrVolumeSize as new in the subclasses, C# supposes we want to break the polymorphism mechanism and invoke the method of the superclass, not the “new” implementation in the subclass.

There is another possibility, though: if our subclasses implement the interface along with inheriting from the superclass, the runtime behavior is again that of invoking the specific class’s implementation, not the superclass’s.

In the following code, our subclasses (PossibleSquare and PossibleCube) inherit from Quad and they hide its AreaOrVolumeSize method, but they also implement the interface directly. In this way, even if they have hidden the superclass’s method, .Net knows that it is their method implementation it has to call, not the superclass’s:

namespace TestInheritanceWithInterfaces

{

interface IAreaOrVolume
{
double AreaOrVolumeSize();
//whatever object implements this interface will have to define its own AreaOrVolumeSize metod
}

class Quad : IAreaOrVolume
{
protected double _width;
protected double _height;
protected double _depth;

public Quad(double width, double height, double depth)
{
_width = width;
_height = height;
_depth = depth;

}

public double AreaOrVolumeSize()
{
return _width * _height * 1;
// this is a Quad. We disregard the depth of the object, as a Quad has an area, not a volume
}

}

class PossibleSquare : Quad, IAreaOrVolume // implementing directly IAreaOrVolume
{
public PossibleSquare(double width, double height, double depth) : base(width, height, depth) { }

public new double AreaOrVolumeSize()
{
return _width * _width * 1;
// this is a Square. We disregard the depth of the object,
// as a Square has an area, not a volume
// we also disregard the height as it is equal to the width
}
}

class PossibleCube : PossibleSquare, IAreaOrVolume // implementing directly IAreaOrVolume
{
public PossibleCube(double width, double height, double depth) : base(width, height, depth) { }

public new double AreaOrVolumeSize()
{
return _width * _width * _width;
// this is a Cube.
// we disregard depth and height as they are both equal to the width
}
}

class Program
{
static void Main(string[] args)
{
IAreaOrVolume thisShape;
// typing our variable with the interface implemented by classes and subclasses allows
// polymorphism

thisShape = new Quad(5,6,1);
Debug.WriteLine(“Quad’s area or volume: {0}”,thisShape.AreaOrVolumeSize());

thisShape = new PossibleSquare(5,6,1);
Debug.WriteLine(“Square’s area or volume: {0}”, thisShape.AreaOrVolumeSize());

thisShape = new PossibleCube (5,6,2);
Debug.WriteLine(“Cubes’s area or volume: {0}”, thisShape.AreaOrVolumeSize());
}
}
}

The result?

This time, more logic:

Quad’s area or volume: 30
Square’s area or volume: 25
Cubes’s area or volume: 125

Alternatives:

Below, we declare PossibleCube as a subclass of PossibleSquare, but do not specify it implements IAreaOrVolume.

class PossibleCube : PossibleSquare // NOT implementing directly IAreaOrVolume

Result?

Quad’s area or volume: 30
Square’s area or volume: 25 (its own implementation)
Cubes’s area or volume: 25 (again, the superclass’s implementation)

Here below, instead, it is PossibleSquare that hides the method’s implementation, and does not implement the interface directly

class PossibleSquare : Quad // NOT implementing directly IAreaOrVolume

class PossibleCube : PossibleSquare, IAreaOrVolume // again implementing directly IAreaOrVolume

The obvious result:

Quad’s area or volume: 30
Square’s area or volume: 30 (again, the superclass’s implementation)
Cubes’s area or volume: 125 (its own implementation)

Static IP addresses for Azure websites that are not hosted as “cloud services” or “VM”s: still impossible for outbound, but workarounds possible

I hope this article is not valid for long and that static IPs will also soon also applicable for Azure websites. At this moment (October 2014), this is not the case.

Microsoft announced at the end of July that you can finally have reserved IPs for VMs and cloud services. Cloud services CAN host websites (the “web” role) but they’re not as easy to deploy as Azure website services (which are elementary).

The details of the procedure to obtain the static IP (for inbound AND outbound traffic) are in this MSDN article here.

The procedure is not very friendly yet: you have to use powershell or Azure’s API. I haven’t seen a graphic interface yet. Moreover, static IPs can – today – only be assigned to newly deployed stuff, not to already-deployed services.

What happens if you still have an Azure “website”, that is the most simple (and agile) way to deploy your own website to the Azure cloud?

Inbound traffic

You CAN have an static IP address for inbound traffic. Here, in an MSDN blog entry, Benjamin Perkins shows how to do it with the help of SSL certificates.

Outbound traffic: there’s the rub

Why would you want your outbound traffic IP to be static? Because there are cases in which your website, in the background, has to call web services which only accept calls from whitelisted IPs. When is this the case?
– financial services (for instance: online payment)
– other paid web services

Should we give up Azure if we need outbound static IP? Not really. There are two ways to overcome the issue of outbound traffic not being static in Azure websites.

1. Azure websites’s IP addresses are not totally dynamic. There IS a range of IPs that your outbound traffic can use. The list is here. If your remote web server needs to know what IP address you’re going to use to make the calls, you can give them the Azure datacenter IP ranges.

What is the problem with this approach? the list is long, whereas web service providers may accept only a few IP addresses.

In October 2014, the West Europe Data Center IP list is long tens of lines. Chances are your web service provider gives you… say ten IPs you can communicate them?

2. You use a static-IP proxy for your websites calls. I have tested this British service called Quotaguard, that I pay for and with whom I have no affiliation whatsoever. It works.

What do they do? they provide you with a proxy server that does have two static IPs you can communicate to your provider as your “whitelisted” IPs. Your Azure traffic that needs whitelisting can pass via Quotaguard.

They have a lot of implementation examples. For .NET, they focus on web forms and http requests that have a proxy property. In case you are using (as it was my case) objects that have no “proxy” porperties, you can create a Proxy object yourself and link it to the .NET framework object “WebRequest”, like this:

using System.Net;

var proxy = new WebProxy(“http://quotaguard_THE_CODE_QUOTAGUARD_GIVES_YOU@eu-west-1-babbage.quotaguard.com:9293“); // you may want to store this URI in the application’s config page in Azure, rather than hardcoding it
            proxy.Credentials = new NetworkCredential(“YourQuotaGuardAccount”, “yourQuotaguardpassword”); // you may want to store credentials in secure config files rather than hardcoding them
            WebRequest.DefaultWebProxy = proxy; // we set the “global” proxy here
            Now you can use your whitelisted webservice call…
Another version of the same code can be found here:
Enjoy!

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=”http://schemas.android.com/apk/res/android&#8221; 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” />
</manifest>

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”>
<intent-filter>
<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” />
</intent-filter>
</activity>
</application>

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.