1 2 3 4 5 6 7 8 9 10 11 12 13

ASP NET MVC - Model Create With List of Model

25 Nov, 2014

This post runs through how to create a form for creating a model with a list of child models using MVC 5 and Razor.

I've been rather quiet on the blogging front lately, I've been working on getting my MVC 5 quiz application up and running on Azure, it's here if anyone wants to give it a go.

One thing I wanted to do while working on the site was allow for a model to be created along with a list of "sub" models; for example when creating a question it would be nice for a user to also create the answers on the same page.

Setup

To demo this we need a model which could "own" some collection of other items. I happened on the perfect example today in the Json.NET source:

Rabbit with a pancake on its head.

...

ASP.NET Identity 2.0 Tutorial - Password Reset and Roles

13 Oct, 2014

Given how much you all enjoyed the previous tutorial, i.e. not at all, I thought I'd write a follow up post. As promised this blog post extends the basic system we created in the main tutorial to add roles and a password reset function.

I won't show how to setup the emails for password reset because I'm too lazy to fill in the form for a free SendGrid account, however plugging emails in should be the easy bit.

Password Reset

The default template provides the controller actions and views for a full password reset function. The user can enter an email address at /Account/ForgotPassword. When posted the action below is called:

public async Task<ActionResult> ForgotPassword(ForgotPasswordViewModel model)
{
    if (ModelState.IsValid)
    {
        var user = await UserManager.FindByNameAsync(model.Email);
        if (user == null || !(await UserManager.IsEmailConfirmedAsync(user.Id.ToString())))
        {
            // Don't reveal that the user does not exist or is not confirmed
            return View("ForgotPasswordConfirmation");
        }
        string code = await UserManager.GeneratePasswordResetTokenAsync(user.Id.ToString());
        var callbackUrl = Url.Action("ResetPassword", "Account", new { userId = user.Id, code = code }, protocol: Request.Url.Scheme);      
        // await UserManager.SendEmailAsync(user.Id, "Reset Password", "Please reset your password by clicking <a href=\"" + callbackUrl + "\">here</a>");
        return RedirectToAction("ForgotPasswordConfirmation", "Account");
    }
    return View(model);
}

I have commented out the email sending part for the reasons mentioned above.

All we need to do is supply our UserManager with a token provider. From the code for the default UserManager:

/// <summary>
/// Used for generating reset password and confirmation tokens
/// </summary>
public IUserTokenProvider<TUser, TKey> UserTokenProvider { get; set; }

As usual Microsoft have made everything easy by giving us a nice interface to implement. This also means you can adapt your password reset to function however you like. For instance you could add an expiry date to the reset token or have a token which is a combination of a Guid and number or two Guids.

For my token provider I'm simply going to generate a new Guid to act as the reset token. This maps onto the nullable reset token field on my user table, I've hidden some stuff here because I don't want you stealing the super secure password hashes ("password" and "password1"):

...

ASP.NET Identity 2.0 Tutorial - EF Free (Post 2)

12 Oct, 2014

Note: This is the second post in a 2 post tutorial on implementing Identity 2.0 without using EF, for post 1 go here.

Now we have our User and UserStore classes we can change the UserManager and SignInManager our application uses. These classes are in the App_Start/IdentityConfig.cs file.

I split the classes out to their own files, ApplicationUserManager.cs and ApplicationSignInManager.cs respectively. In their unmodified state these classes inherit from the classes provided by the Identity library.

ApplicationUserManager

The manager provides many methods to use in our controllers, a few examples are:

public virtual Task<IdentityResult> ResetAccessFailedCountAsync(TKey userId);
public virtual Task<IdentityResult> ResetPasswordAsync(TKey userId, string token, string newPassword);
public virtual Task SendEmailAsync(TKey userId, string subject, string body);

The manager mainly delegates to classes it owns such as the user store to run these methods. The default template UserManager is shown below:

public class ApplicationUserManager : UserManager<ApplicationUser>
{
    public ApplicationUserManager(IUserStore<ApplicationUser> store)
        : base(store) { }

    public static ApplicationUserManager Create(IdentityFactoryOptions<ApplicationUserManager> options, 
        IOwinContext context) 
    {
        var manager = new ApplicationUserManager(
            new UserStore<ApplicationUser>(context.Get<ApplicationDbContext>()));

        // Configure validation logic for usernames
        manager.UserValidator = new UserValidator<ApplicationUser>(manager)
        {
            AllowOnlyAlphanumericUserNames = false,
            RequireUniqueEmail = true
        };

        // Configure validation logic for passwords
        manager.PasswordValidator = new PasswordValidator
        {
            RequiredLength = 6,
            RequireNonLetterOrDigit = true,
            RequireDigit = true,
            RequireLowercase = true,
            RequireUppercase = true,
        };

        [CONTENT REMOVED TO SAVE SPACE...]
        return manager;
    }
}

Because everything takes arguments based on interfaces we've already created our classes for, the rewrite is very simple. Firstly we replace all instances of ApplicationUser with our class which implements IUser, in our case MyUser:

public class ApplicationUserManager : UserManager<MyUser>
{
    public ApplicationUserManager(IUserStore<MyUser> store)
        : base(store)
    {
        this.UserValidator = new MyUserValidator<MyUser, string>();
    }

    public static ApplicationUserManager Create(IdentityFactoryOptions<ApplicationUserManager> options, 
        IOwinContext context)
    {
        var manager = new ApplicationUserManager(new MyUserStore<MyUser>());
        // Configure validation logic for usernames
        manager.UserValidator = new UserValidator<MyUser>(manager)
        {
            AllowOnlyAlphanumericUserNames = false,
            RequireUniqueEmail = true
        };

        // Configure validation logic for passwords
        manager.PasswordValidator = new PasswordValidator
        {
            RequiredLength = 3,
            RequireNonLetterOrDigit = false,
            RequireDigit = false,
            RequireLowercase = true,
            RequireUppercase = false
        };

        // Configure user lockout defaults
        manager.UserLockoutEnabledByDefault = false;

        manager.EmailService = new EmailService();
        manager.SmsService = new SmsService();

        return manager;
    }
}

I set the password requirements to be super weak for manual testing because typing secure passwords repeatedly was too much like hard work!

We also remove the default UserStore which depends on Entity Framework and insert our own MyUserStore (which in this tutorial also depends on EF but with no requirement to pass a DbContext to the constructor). Additionally all parts setting up 2 Factor Auth are removed.

...

ASP.NET Identity 2.0 Tutorial - Entity Framework Free

11 Oct, 2014

So in this post I detailed how to use Asp Identity with Entity Framework Database First. However when I started a new MVC project and tried to follow the steps nothing worked. ASP Identity 2.0 has ruined everything by introducing many breaking changes.

This post will guide you on how to setup Identity 2.0 without Entity Framework. The original post was a lot longer but I've tried to cut down a lot of the rambling, for a great step-by-step guide to Identity 2.0 see this excellent CodeProject post by John Atten.

Create a New Project

Let's create a new MVC project using Individual User Accounts as shown below to see what the template gives us:

The default new project screen.

...

Minify Json using JSON.NET

25 Sep, 2014

In my current project I'm using Json stored in the SQL Server database to replicate the storage capability of the browser Session but allowing the data to persist on the user reloading/leaving the page.

One of the challenges is to store the serialized object in as few characters as possible while preserving meaning.

Without touching the settings, Json.Net stores the strings without extraneous whitespace, but even serializing a fairly small aggregate object can use a lot of characters.This post details a couple of the features I've used to minimise the number of characters.

Store Booleans as Integers in Json

JSON.NET supports custom conversions using a class which inherits from JsonConverter:

public class BooleanConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return typeof(bool).IsAssignableFrom(objectType);
    }

    public override void WriteJson(JsonWriter writer,
        object value, JsonSerializer serializer)
    {
        bool? source = value as bool?;
        if (source == null) { return; }

        int valueAsInt = ((bool)source) ? 1 : 0;

        writer.WriteValue(valueAsInt);
    }

    public override object ReadJson(JsonReader reader, Type objectType,
        object existingValue, JsonSerializer serializer)
    {
        bool returnValue = (Convert.ToInt32(reader.Value) == 1);

        return returnValue;
    }
}

This converter will store booleans as 1 and 0 rather than true and false; this saves 3 and 4 characters respectively.

Shorten Field and Property Names

By using the built in [JsonProperty("Name")] we can save space in the serialized object. If we define one letter aliases for our properties we save a lot of space, especially when serializing an array of objects:

[JsonProperty("b")]
public bool IsAThing { get; set; } 

If the full object has IsAThing = false the string representing the serialized object stores this as "b":0 which is the shortest representation possible (unless you set the default value to false and only serialize where the boolean value is true).

Serializing an HtmlString

This isn't a space saving tip but where you need HtmlStrings to be serialized and deserialized you can use the converter below:

...
1 2 3 4 5 6 7 8 9 10 11 12 13