Telerik blogs

You may have read my colleagues’ posts about the ConferenceBuddy apps they are building to demonstrate the Telerik Windows 8, Windows Phone 8, and Windows Forms controls.  The ConferenceBuddy apps are intended to provide data collection capabilities for representatives at Tech Conferences.  The missing piece of this great data collection activity is a capability to send the information “home” for analysis.  That is where this article and my participation in ConferenceBuddy begins; I shall create a central set of web services for the client apps. 

A WebAPI for all of us

In 2012, Microsoft added WebAPI to the ASP.Net framework as a new method to generate REST-based services.  REST services rely on the Http protocol to define the methods and formats of the data being transferred, and WebAPI conforms to these standards brilliantly.  With ASP.Net WebAPI, we have a tool that is already configured for interactions with clients that send XML or JSON formatted data.  WebAPI will simply adapt to the content-type submitted and handle it appropriately.  This management of data content-types is a core tenet of the WebAPI framework that immediately solves our content negotiation problems between each of the unique client applications.

In the case of the ConferenceBuddy apps, they are all storing data in JSON format, so we will not need to write any additional content format handlers.  I am left with the task to construct the three APIs, one for storing the event meta-data, one for the contacts data, and a final one for authentication.

Project Configuration

I am getting started with ASP.Net 2012.2 installed in Visual Studio.  The project I am going to create for ConferenceBuddy will start with the “ASP.Net Web Forms application” template (more on that later) and will have the WebAPI capabilities added to it.  I want to keep everything for this effort very self-contained in one project, so I added a Models folder where I can write up a C# implementation of the JSON objects that the ConferenceBuddy client apps are collecting.

This is where one of the really cool new features of ASP.Net 2012.2 comes in.  I have samples of the JSON documents from Jesse Liberty’s Windows 8 application, with these sample files, I can very quickly generate my EventViewModel and ContactViewModel objects for the service.  From the original JSON files, I simply copied the text of one instance of an object and in a new class file in Visual Studio, I can paste the JSON as a C# class.


Figure 1 - Paste JSON as Classes

Now I need a little cleanup work to give the pasted class a name and to add some data annotations to the fields to ensure that we receive valid data.  I quickly have an EventViewModel that looks like a natural C# class:

public class EventViewModel
{
 
  public EventViewModel()
  {
    attributes = new Dictionary<string, string>();
  }
   
  public int id { get; set; }
 
  public string name { get; set; }
 
  public string city { get; set; }
 
  public string state { get; set; }
 
  public string country { get; set; }
 
  // Additional fields...
}
Code Listing 1 - EventViewModel class

With a simple ViewModel constructed, I can configure a WebAPI controller to receive and transmit EventViewModel objects.  This EventsController will reach into an Entity Framework data context to interact with a Sql database.  I prefer to store these objects in an “api” folder in my project, and that is where I will create a WebAPI EventsController.  After I add some calls into the Entity Framework datacontext I have:

public class EventsController : ApiController
{
  // GET api/<controller>
  public IEnumerable<EventViewModel> Get()
  {
 
    var ctx = new CbContext();
    return ctx.Events.ToArray();
 
  }
 
  // GET api/<controller>/5
  public EventViewModel GetEvent(int id)
  {
    var ctx = new CbContext();
    return ctx.Events.FirstOrDefault(e => e.id == id);
 
    if (outEvent == null)
      throw new HttpResponseException(new HttpResponseMessage(System.Net.HttpStatusCode.NotFound));
 
  }
 
  // POST api/<controller>
  public HttpResponseMessage Post(EventViewModel evt)
  {
 
    if (!this.ModelState.IsValid)
    {
      return Request.CreateResponse(System.Net.HttpStatusCode.ExpectationFailed, "Event submitted is invalid");
    }
 
    var ctx = new CbContext();
     
    ctx.Events.Add(evt);
    ctx.SaveChanges();
 
    var outResponse = Request.CreateResponse(System.Net.HttpStatusCode.Created);
    var newEventUrl = Url.Route(null, new { id = evt.id });
    outResponse.Headers.Location = new Uri(Request.RequestUri, newEventUrl);
    return outResponse;
 
  }
}
Code Listing 2 : EventsController source code

Notice how the Post method does not return void as defined in the default controller template, but rather returns an HttpResponseMessage.  This is a good practice, as we want to issue appropriate status codes in response to the action submitted by the client.  In order to emit an appropriate HttpStatusCode, we use the Request.CreateResponse statements to set the HttpStatusCode and an appropriate message content (if any) to return.  Additionally, I have set the Location header to indicate the location that the client can fetch the new event they have posted.

Now our client apps can interact with this controller at: /api/Events to fetch or submit event data.  There is however one catch, we want to ensure that this application is secured, so that no rogue information is loaded into the datastore.  WebAPI has an answer for that, and it is simpler than it sounds.

Service Security

The authentication and authorization model in ASP.Net is simple and elegant.  It is very easy to extend the authentication model to meet your particular needs, and in the case of our WebAPI services, we shall use it in place with no modifications.  What does that mean for actual implementation?  Simple:  Just add an Authorize attribute to the top of the controllers that we want to ensure users are logged in to be able to access:

[Authorize()]
public class EventsController : ApiController
{
Code Listing 3 - Authorize Attribute applied to EventsController

Finally, we need to provide a mechanism for the clients to authorize without going through the standard web forms login screen and authentication mechanisms.  For this operation, I will create an Authorization controller called AuthController that will process login requests on the POST action:

public class AuthController : ApiController
  {
 
    [HttpGet]
    public bool IsAuthenticated()
    {
      return User.Identity.IsAuthenticated;
    }
 
    [HttpPost]
    public HttpResponseMessage Authenticate([FromBody]Models.LoginViewModel auth)
    {
 
      var authenticated = Membership.ValidateUser(auth.UserName, auth.Password);
       
      if (!authenticated)
        return Request.CreateResponse<bool>(HttpStatusCode.Unauthorized, false);
       
      var cookie = FormsAuthentication.GetAuthCookie(auth.UserName, false);
      var response = Request.CreateResponse<bool>(HttpStatusCode.OK, true);
      response.Headers.AddCookies(new CookieHeaderValue[1]
      {
        new CookieHeaderValue(cookie.Name, cookie.Value)
      });
 
      return response;
 
    }
 
  }
Code Listing 4 - Authorization WebAPI controller

If you have written the authentication methods for an ASP.Net website in the past, this should look familiar to you.  The input to the Authenticate method is a LoginViewModel (whose sole properties are UserName and Password) from the body of the POST.  The method does some standard FormsAuthentication processes, and then returns an HttpResponse with a status indicator and the appropriate Forms Authentication cookie when the action is authenticated properly.

To authenticate properly on subsequent requests, the client applications simply need to include the authentication cookie in the headers of their calls to the WebAPI.

Summary

In this article, we showed how to quickly take JSON input and convert it into a C# class that can be used with WebAPI and Entity Framework to persist data to a database from client applications.  I wrote a simple authentication controller to allow our WebAPI interactions to be secured with standard ASP.Net Forms Authentication.  The source code for this article is available to download:  ConferenceBuddy WebAPI Source

With this service in place, I think it is just about time to talk to the other Telerik Evangelists so that they can interact with our service and start sharing data between their applications.  After reading all of their great articles about ConferenceBuddy, I think it is about time that someone shows them what a mobile web application can do.  Next time, I will show you how we can use the AJAX controls with the new mobile routing features of ASP.Net 2012.2 to present a great user interface for ConferenceBuddy.


About the Author

Jeffrey T. Fritz

Jeffrey T. Fritz is a Microsoft MVP in ASP.Net and an ASPInsider with more than a decade of experience writing and delivering large scale multi-tenant web applications. After building applications with ASP, ASP.NET and now ASP.NET MVC, he is crazy about building web sites for all sizes on any device. You can read more from Jeffrey on his personal blog or on Twitter at @csharpfritz. Google Profile


Comments

Comments are disabled in preview mode.