Community

This is a departure from the types of post I normally do so please bear with me.

Early in my career I followed some bad advice that steered me away from the great development community that Nashville has to offer. Following that advice is the thing I regret most in my career. That advice is what lead me down the path of the dark matter developer that I mention in the about page for this site.

I spent a lot of years working very hard at my job with my only interaction with other developers being my co-workers. It was comfortable and the easy thing to do. I did not realize how much I was limiting myself. Limiting my growth as a developer, but more so limiting my personal development.

Thankfully this is not where the story ends. A lot of life happened and I ended up being exposed to a group of people who loved being involved with the Nashville development community. They were excited by what they do and involved at levels I had never seen. It was a breath of fresh air and a turning point for me. I am a shy and introverted person but exposure to the community helped me to start getting passed my shyness.

To start I began attending the local .Net User Group. For me this user group was a great place to start. I could listen to the speaker and slip out after the talk was over without too much interaction with others. Over time interactions got easier and I met a ton of great people. User groups are a great for learning new things, but I have come to realize that the connections made with other people are by far the most valuable benefit. I have even expanded to some social only events like the Geek Social.

If you are not involved with the community in your area I encourage you to start. Get to know your fellow developers. They are the greatest resource to be found.

If you need more convincing check out this content from Scott Hanselman and Rob Conery.

Community Read More »

Adding Authorize to a Web API

In the post Aurelia with ASP.NET 5 and Web API I removed the authorize attribute from the contacts API controller to reduce complexity. That change simplified some things but it also effectively made the API useless for multiple users.

In this post I am going to add back in authorization as well as making sure a user identifier is used in contact creation and retrieval. Also note that this authorization is taking place in the web application not via the API so the user must logged in via the main site before access to the API is allowed.

All the changes are in the controller class that needs to be protected. First add two new namespaces.

using Microsoft.AspNet.Authorization;
using System.Security.Claims;

Microsoft.AspNet.Authorization is where the Authorize attribute is found and System.Security.Claims contains an extension method on to the User class to make it easy to get the user ID.

Next add the Authorize attribute to the class level if the whole class should require authorization or at the function level if only some functions need authorization.

[Authorize]
[Route("api/[controller]")]
public class ContactsController : Controller

Next add a filter to the query for contacts to makes sure a user only sees their contacts. User is provided by the Controller base class and the GetUserId is the extension method from System.Security.Claims namespace referenced above.

private IQueryable<Contact> GetContacts()
{
    var contacts = from c in _dbContext.Contacts
                             .Include(c => c.Addresses)
                             .Include(c => c.EmailAddresses)
                             .Include(c => c.PhoneNumbers)
                   where c.UserId == User.GetUserId()
                   select c;
    return contacts;
}

In the create function, which handles HTTP post, the contact user ID must be set based on the current user before the contact is added to the DB context.

[HttpPost]
public async Task Create([FromBody] Contact contact)
{
    if (contact == null)
    {
        return HttpBadRequest();
    }

    if (!ModelState.IsValid)
    {
        return new BadRequestObjectResult(ModelState);
    }

    contact.UserId = User.GetUserId();

    _dbContext.Add(contact);
    await _dbContext.SaveChangesAsync();
    return CreatedAtRoute("GetById",
                          new
                          {
                              controller = "Contacts",
                              id = contact.Id
                          },
                          contact);
}

Adding Authorize to a Web API Read More »

Aurelia Routing with a Parameter

A post covering the same concepts but with updated versions of ASP.NET and Aurelia can be found here.

I have spent some time building out the client side of my contacts application using Aurelia. For a starting point with Aurelia check out my previous post on Aurelia with ASP.NET 5 and Web API and Start Aurelia from an ASP.NET 5 Controller. In this post I am going to cover passing a parameter via routing.

Keep in mind I am serving this application from ASP.NET 5 and all the Aurelia related files are in the wwwroot folder of my ASP.NET 5 project. App.html and app.js in wwwroot with the remaining Aurelia files in an Aurelia folder.

project

In app.js a new route was added for the detail view. Make special note that the new route expects an id parameter.

import 'lib/bootstrap/dist/js/bootstrap';

export class App {
    configureRouter(config, router) {
        config.title = 'Contacts';
        config.map([
            {
                route: ['', 'list'],
                name: 'list',
                moduleId: './Aurelia/list',
                nav: true,
                title: 'List'
            },
            {
                route: 'add',
                name: 'add',
                moduleId: './Aurelia/add',
                nav: true,
                title: 'Add'
            },
            {
                route: 'detail/:id',
                name: 'detail',
                moduleId: './Aurelia/detail',
                nav: false,
                title: 'Detail'
            }
        ]);

        this.router = router;
    }
}

In list.html the contacts need to be rendered with an anchor that will lead to the proper detail view. To accomplish this Aurelia has a route-href custom attribute that can be used with an anchor.

<template>
    <div>
        <ul class="list-group">
            <li repeat.for="contact of contacts" class="list-group-item">
                <h4 class="list-group-item-heading">
                    <a route-href="route: detail; 
                                   params.bind: {id:contact.Id}">
                        ${contact.Name}
                    </a>
                </h4>
                <p repeat.for="emailaddress of contact.EmailAddresses"
                   class="list-group-item-text">
                    <a href="mailto:${emailaddress.Address}">
                        ${emailaddress.Address}
                    </a> 
                </p>
            </li>
        </ul>
    </div>
</template>

With route-href route, set to detail above, defines the name of the route from the route config. Parms.bind creates an object with an id property which is bound to the id defined on the route. Any property on the object that does not have a in the route definition will be added to the query string.

When one of the routing links is clicked then on activation detail.js queries the Web API for the contact details based on the id in the parms.

import {inject} from 'aurelia-framework';
import {HttpClient, json} from 'aurelia-fetch-client';
import 'fetch';

@inject(HttpClient)
export class Detail{
    contact = '';

    constructor(http){
        http.configure(config => {
            config
              .useStandardConfiguration()
              .withBaseUrl('https://localhost:13102/api/');
        });

        this.http = http;
    }

    activate(params) {
        return this.http.fetch('contacts/' + params.id)
          .then(response => response.json())
          .then(contact => this.contact = contact);
    }
}

No real new concepts in the above. On active the Web API is called and the resulting json is used to populate a contact property.

The detail view then uses the contact property to bind to the contact information.

<template>
    <div>
        <div class="row">
            <label class="label label-info">${contact.Id}</label>
        </div>
        <div class="row">
            <label class="col-sm-1 control-label">Name</label>
            <div class="col-sm-11">
                <p class="control-label">${contact.Name}</p>
            </div>
        </div>
        <div class="row">
            <label class="col-sm-1 control-label">Addresses</label>
            <div class="col-sm-11">
                <p repeat.for="address of contact.Addresses"
                   class="list-group-item-text">
                    ${address.City}, ${address.State}
                </p>
            </div>
        </div>
        <div class="row">
            <label class="col-sm-1 control-label">Email Addresses</label>
            <div class="col-sm-11">
                <p repeat.for="emailaddress of contact.EmailAddresses"
                   class="list-group-item-text">
                    <a href="mailto:${emailaddress.Address}">${emailaddress.Address}</a>
                </p>
            </div>
        </div>
        <div class="row">
            <label class="col-sm-1 control-label">Phone Numbers</label>
            <div class="col-sm-11">
                <p repeat.for="phone of contact.PhoneNumbers"
                   class="list-group-item-text">
                    ${phone.Number}
                </p>
            </div>
        </div>
    </div>
</template>

The above results in the following view.

contactDetailView

Aurelia Routing with a Parameter Read More »