Adding Dependency Injection to your ASP.NET MVC Twilio app using MEF (Managed Extensibility Framework)

Adding Dependency Injection to your ASP.NET MVC Twilio app using MEF (Managed Extensibility Framework)

http://www.twilio.com/blog/2012/11/adding-dependency-injection-to-your-asp-net-mvc-twilio-app-using-mef.html

Thanks for the Reblog Twilio!

TwilioCON 2012 Developer & Doers @ San Francisco, CA – Day 2

TwilioCON 2012 Hackathon was fun, teamed up with John Palmer @citriusjohn and kicked around a few ideas however figured it would be best if we waited for TwilioCON 2013 to actually compete.

It was great to finally meet some of the people I’ve done some work with remotely and/or through online meetings e.g. Evan Cummack (@cummack), Devin Rader (@devinrader), among other people at TwilioCON. Another highlight of the second day was hearing the good news that we are officially been approved to as an Authorized Twilio SI (Systems Integrator), thanks Greg, Cheetan, and the rest of Twilio’s SI division for making this happen. Wrapping up I had a blast, and hopefully we can do it again next year…!

TwilioCON 2012 Developer & Doers @ San Francisco, CA – Day 1

Had an awesome day yesterday @ TwilioCON 2012 here at San Francisco, CA. Attended some pretty interesting key notes and lab sessions. I really appreciate some of the new features added especially working with call queues (http://www.twilio.com/voice/features/queue) with Twilio Client (http://nuget.org/packages/Twilio.Client).

The demo of full browser soft phone was totally awesome, and having almost full Twilio Client ability on the client side as you would on the server side was also rocked! As day one of TwilioCon 2012 was wrapping up and I started packing, guess what?! Saw Scott Guthrie and fellows walk through the door, will keep you guys posted on what this is about in tomorrows blog, or you can keep an eye on my Twitter (http://twitter.com/lelong37) for updates on this.

Last but not least thanks for the Twilio VIP Dinner invite, had a blast!

Two-Factor Authentication ASP.NET MVC 4 Registration with Twilio SMS

Two-Factor Authentication ASP.NET MVC 4 Registration with Twilio SMS

http://www.twilio.com/blog/2012/10/multi-step-asp-net-mvc-4-registration-with-sms-using-twilio-cloud-communication-and-simplemembershipprovider-for-increased-user-validity.html

Thanks for the Reblog Twilio!

Seed Users and Roles with MVC 4, SimpleMembershipProvider, SimpleRoleProvider, Entity Framework 5 CodeFirst, and Custom User Properties

I’ve been Googling over the weekend and so far didn’t find any articles out there on how integrate EF5 CodeFirst nicely with SimpleMembership and at the same time, seeding some of your users, roles and associating users to roles while supporting custom fields/properties during registration, hence this blog post.

I think this is a nice to have, especially during PoC development where you could be developing features that depend on authentication and authorization while making schema changes with EF CodeFirst. The last thing you want to do is run update-database for migrations and have to manually re-insert/re-seed all your users, roles and associating the two every time you ran migrations (e.g. update-database -force from the Package Manager Console).

First, create an “Internet Application” ASP.NET MVC4 Project, because this is the only out of the box MVC template that has the new SimpleMembershipProvider wired up out of the box. One of the features I like the most about the SimpleMembershipProvider is it gives you total control of the highly requested “User” table/entity. Meaning you integrate SimpleMembershipProvider with your own user table, as long as it has a UserId and UserName fields in your table.

Obviously there are many more features in SimpleMembership provider, here are some links in this regard:

Explicitly wire up the providers even though this is implied, so that when do run the “update-database” command from the Package Manager Console for migrations we can use the native “Roles” Api.

In the “System.Web” Section add:


    <roleManager enabled="true" defaultProvider="SimpleRoleProvider">
      <providers>
        <clear/>
        <add name="SimpleRoleProvider" type="WebMatrix.WebData.SimpleRoleProvider, WebMatrix.WebData"/>
      </providers>
    </roleManager>
    <membership defaultProvider="SimpleMembershipProvider">
      <providers>
        <clear/>
        <add name="SimpleMembershipProvider" type="WebMatrix.WebData.SimpleMembershipProvider, WebMatrix.WebData" />
      </providers>
    </membership>

Let’s add a custom field to the User table by adding a Mobile property to the UserProfile entity (MVC4SimpleMembershipCodeFirstSeedingEF5/Models/AccountModel.cs).


    [Table("UserProfile")]
    public class UserProfile
    {
        [Key]
        [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
        public int UserId { get; set; }
        public string UserName { get; set; }
        public string Mobile { get; set; }
    }

Enable EF5 CodeFirst Migrations

Seed your Roles and any Users you want to provision, also note the WebSecurity.InitializeDatabaseConnection method we are invoking. This method is what tells SimpleMembership which table to use when working with Users and which columns are for the UserId and UserName. I’m also going to demonstrate how you can hydrate additional custom columns such as requiring a User’s mobile number when registering on the site.


#region

using System.Data.Entity.Migrations;
using System.Linq;
using System.Web.Security;
using MVC4SimpleMembershipCodeFirstSeedingEF5.Models;
using WebMatrix.WebData;

#endregion

namespace MVC4SimpleMembershipCodeFirstSeedingEF5.Migrations
{
    internal sealed class Configuration : DbMigrationsConfiguration<UsersContext>
    {
        public Configuration()
        {
            AutomaticMigrationsEnabled = true;
        }

        protected override void Seed(UsersContext context)
        {
            WebSecurity.InitializeDatabaseConnection(
                "DefaultConnection",
                "UserProfile",
                "UserId",
                "UserName", autoCreateTables: true);

            if (!Roles.RoleExists("Administrator"))
                Roles.CreateRole("Administrator");

            if (!WebSecurity.UserExists("lelong37"))
                WebSecurity.CreateUserAndAccount(
                    "lelong37",
                    "password",
                    new {Mobile = "+19725000000"});

            if (!Roles.GetRolesForUser("lelong37").Contains("Administrator"))
                Roles.AddUsersToRoles(new[] {"lelong37"}, new[] {"Administrator"});
        }
    }
}

Now, run the update-database -verbose command from Package Manager Console, we are using the -verbose switch so that we can get better visibility on what’s getting executed on SQL. Notice the Mobile field is being created.

Let’s go ahead and do a sanity check and make sure all of our Users and Roles were provisioned correctly from the Seed method in our migration configuration, by executing a few queries.


SELECT TOP 1000 [UserId]
      ,[UserName]
      ,[Mobile]
  FROM [aspnet-MVC4SimpleMembershipCodeFirstSeedingEF5].[dbo].[UserProfile]
  
  SELECT TOP 1000 [RoleId]
      ,[RoleName]
  FROM [aspnet-MVC4SimpleMembershipCodeFirstSeedingEF5].[dbo].[webpages_Roles]
  
  SELECT TOP 1000 [UserId]
      ,[RoleId]
  FROM [aspnet-MVC4SimpleMembershipCodeFirstSeedingEF5].[dbo].[webpages_UsersInRoles]

Results

  • Users were inserted
  • Roles were provisioned
  • The user “LeLong37” was added and associated to the Administrator role

Finally for a sanity check, let’s go ahead and run the app and sign-in with the provisioned user from our Seed method.

Successfully authenticated with our seeded provisioned user (thought I’d add a blue star badge to the screenshot to add some humor 😛 )!

One last thing, let’s go ahead and modify our Register view, Register model and AccountController to gather the user’s mobile number during registration.

Register View (Register.cshtml)


@model MVC4SimpleMembershipCodeFirstSeedingEF5.Models.RegisterModel
@{
    ViewBag.Title = "Register";
}

<hgroup class="title">
    <h1>@ViewBag.Title.</h1>
    <h2>Create a new account.</h2>
</hgroup>

@using (Html.BeginForm()) {
    @Html.AntiForgeryToken()
    @Html.ValidationSummary()

    <fieldset>
        <legend>Registration Form</legend>
        <ol>
            <li>
                @Html.LabelFor(m => m.UserName)
                @Html.TextBoxFor(m => m.UserName)
            </li>
            <li>
                @Html.LabelFor(m => m.Password)
                @Html.PasswordFor(m => m.Password)
            </li>
            <li>
                @Html.LabelFor(m => m.ConfirmPassword)
                @Html.PasswordFor(m => m.ConfirmPassword)
            </li>
            <li>
                @Html.LabelFor(m => m.Mobile)
                @Html.TextBoxFor(m => m.Mobile)
            </li>
        </ol>
        <input type="submit" value="Register" />
    </fieldset>
}

@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
}


Register model (AccountModel.cs)


    public class RegisterModel
    {
        [Required]
        [Display(Name = "User name")]
        public string UserName { get; set; }

        [Required]
        [StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
        [DataType(DataType.Password)]
        [Display(Name = "Password")]
        public string Password { get; set; }

        [DataType(DataType.Password)]
        [Display(Name = "Confirm password")]
        [Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]
        public string ConfirmPassword { get; set; }

        [Required]
        [DataType(DataType.PhoneNumber)]
        [Display(Name = "Mobile")]
        public string Mobile { get; set; }
    }


Register Action (AccountController.cs)


        [HttpPost]
        [AllowAnonymous]
        [ValidateAntiForgeryToken]
        public ActionResult Register(RegisterModel model)
        {
            if (ModelState.IsValid)
            {
                // Attempt to register the user
                try
                {
                    WebSecurity.CreateUserAndAccount(
                        model.UserName, 
                        model.Password, 
                        new { Mobile = model.Mobile }, 
                        false);

                    WebSecurity.Login(model.UserName, model.Password);
                    return RedirectToAction("Index", "Home");
                }
                catch (MembershipCreateUserException e)
                {
                    ModelState.AddModelError("", ErrorCodeToString(e.StatusCode));
                }
            }

            // If we got this far, something failed, redisplay form
            return View(model);
        }

Finally, let’s register.

Let’s go ahead and run our SQL queries again and make sure the mobile number was actually saved to our UserProfile table during the registration.

Sweet! Registration successful, with mobile number saved to the UserProfile table.

Happy Coding…!

Download Sample Application: http://blog.longle.net/2012/09/26/multi-step-asp-net-mvc-4-registration-with-sms-using-twilio-cloud-communication-and-simplemembershipprovider-for-increased-user-validity/