Steve Moseley

"To err is human. To really screw up takes a computer." - Dilbert

How to Set an Identity Column Using Code First for Entity Framework In the DbContext

clock August 28, 2010 04:26 by author steve

I did not see this in any documentation any where so I thought I would just do a quick post about it.

If you want to set a column as an Identity in code and then create the database schema from that code, you can annotate your entity as the Entity Framework Team has shown in their post about Data Annotations. The attribute to do this is the StoreGeneratedAttribute.

I don’t want to have any attributes on my entities so I would rather do it my Repository class which is derived from DbContext as Scott Hanselman shows how to do in his post about the Magical Unicorns.

In this quick example I am going to set my Role Entity’s RileId property as an identity column.

Here is my Role Entity

   1: using System.Collections.Generic;
   2:  
   3: namespace AviBlog.Core.Entities
   4: {
   5:     public class Role
   6:     {
   7:         public int RoleId { get; set; }
   8:         public string RoleName { get; set; }
   9:  
  10:         public virtual ICollection<User> Users { get; set; }
  11:     }
  12: }

 

Notice, no attributes on my Entity.

Here is my Repository Class which is derived from the DbContext base class.

   1: using System.Data.Entity;
   2: using System.Data.Metadata.Edm;
   3: using AviBlog.Core.Entities;
   4:  
   5: namespace AviBlog.Core.Repositories
   6: {
   7:     public class PostRepository : DbContext
   8:     {
   9:         public DbSet<Category> Categoryies { get; set; }
  10:         public DbSet<Comment> Comments { get; set; }
  11:         public DbSet<Post> Posts { get; set; }
  12:         public DbSet<Profile> Profiles { get; set; }
  13:         public DbSet<Rating> Ratings { get; set; }
  14:         public DbSet<Tag> Tags { get; set; }
  15:         public DbSet<User> Users { get; set; }
  16:         public DbSet<Role> Roles { get; set; }
  17:  
  18:         public PostRepository() : base("aviBlog")
  19:         {
  20:         }
  21:  
  22:         protected override void OnModelCreating(System.Data.Entity.ModelConfiguration.ModelBuilder modelBuilder)
  23:         {
  24:             modelBuilder.Entity<Role>().Property(x => x.RoleId).StoreGeneratedPattern = StoreGeneratedPattern.Identity;
  25:             base.OnModelCreating(modelBuilder);
  26:         }
  27:  
  28:         
  29:     }
  30: }

In the OnModelCreating method, that I am overriding, I am setting the property of the Role entity using Property extension, and that is the magic that will set the identity for the database column.

So at this point, I can reset the database schema by using the Database object like below:

   1: Database.SetInitializer(new RecreateDatabaseIfModelChanges<PostRepository>());

 

Hope that helps!



Teched 2010 - Internet Explorer 9

clock June 8, 2010 17:09 by author Steve

Intro

The first session of interest I went to for the second day was a session on the new features in Internet Explorer 9. Firsts message in this session was: STOP USING IE 6!

Yes! Even Microsoft wants you to stop using IE 6. Of course, they will point out that when IE 6 was released, it was more standards compliant than the major player at the time, Netscape 4, but admittedly they also point out that they dropped the ball after that and let other competitors pass them.

The good thing is Microsoft is trying to make a mends, and I must say that I was impressed with direction they are going with IE 9.

If you are interested in seeing for your self you can visit their web site at http://ie.microsoft.com/testdrive/.

Performance

During the first part of the session, a bar chart was presented comparing all of the major browser players JavaScript engine.  The first bar on the chart represented IE 8, and I was really surprised to see how slow IE 8 was. It must have been at least four or five time slower than the fastest browser JavaScript Engine, Chrome. However, the latest release of the IE 9, is very close and is in fact faster than the latest Firefox JavaScript engine and even its beta release too.

Where IE 9 really shines in performance is its graphics accelerator engine. There was a demo of moving graphics on a web page and IE 9  was able to processed it seamlessly and when the same demo was done in Chrome it was much slower and very choppy.

HTML 5

IE 9 will have full support of HTML 5 with features such as: SVG1.1 video, and audio. If you want to learn more about SVG there is a very good open source graphic editor you can play with called Inkscape.

Other things HTML 5 has is a new function called DOMContentloaded which allows you specify that some images should not be loaded until the DOM is completely loaded. For example, this is a good approach for websites that want to show third party ads, but do not want those ads to hinder the time it takes to load the web page. By forcing those ads to load at the end the webpage will appear to load faster.

CSS3

Turning to CSS3, a neat feature is that you will be able filter styles based on what client is accessing the site and other criteria such as what screen size the client has. Called media queries , this feature provides the flexibility to choose what styles to load based on media types.

For example you can conditionally load a style sheet based on whether the client is a browser or a printer:

<link rel="stylesheet" type="text/css" media="screen" href="sans-serif.css">
<link rel="stylesheet" type="text/css" media="print" href="serif.css">

CSS3 also allows provides more ways for you to select elements. For example input:not(enabled) will only style an input element that is not enabled.

CSS3 provides more granular control over colors allowing you to control things like opacity and even making the opacity increase in value as the color progresses through an element.

Debug Tools

IE 9 has added some new functionality to their debug tool. The main feature being the Network tab. Similar to Fiddler, except now incorporated in the browser, this tab will allow you to watch what is being requested and the response that is coming back, including what is contained in the header.

Conclusion

Thats all I have for not but  check back and I will update the site with other sessions I have attended.



Microsoft TechEd 2010 - Its All About the Cloud

clock June 7, 2010 17:42 by author Steve

I had the chance to see the Microsoft Teched Keynote today mainly presented by Bob Muglia, and unlike previous TechEd keynotes I have attended--actually I have only attended one in 2007--it was all business and no fluff. No side celebrities to some lame skit this time around. There were no earth shattering announcements made today although today they made a major push to go to the cloud which I thought was pretty interesting.

The main drive of the keynote was all about cloud computing. It was the overall theme that pretty much drove the whole keynote address. Each topic that was presented somehow tied back to the cloud. As a matter of fact, one of the demos was of an application that allowed user to be authenticated and recognized by a website via Active Directory profiles without that user actually having to be on the premises where that website is hosted. This was done by hosting the Activity Directory profiles in the cloud via Azure. Seems a pretty scary thing to do, but Muglia emphases as one of his points that the emphasis of this drive was that it was secure.

Muglia announced today that Visual Studio 2010, will now have the capabilities to develop applications specifically for Azure. From within Visual Studio you can specify things like how big your virtual environment will be, and you will be able to deploy directly to Azure with tracing of the deployment provided.

Other announcements that were made that:

  • The AppFabric plug in for IIS 7 is now available in RTM. This will allow IT to better manage deployments, diagnose and monitor WCF services, and provide a more flexible and scalable caching alternative to the current ASP.Net caching.
  • Windows Server R2 SP1 and Windows 7 SP1 will be available in July.
  • A new version of Windows Communicator will be available which will provide better conferencing (including video) as well as a "big brother" function that will analyze a user mail and other data and determine what skill-sets they have so someone in the company can search on that skill-set and give you a ring if you have it.  Sounds a bit scary to me.
  • Full development capability for the Windows 7 Phone will be able to be done in Visual Studio 2010 and Silverlight. This is a good sign that Microsoft still wants to be in the phone market although I think they still have a ways to go if they want catch up to the iPhone. Seems they are going after the business phone market.
  • Windows 9 will have full support of HTML 5 and have graphics acceleration for faster graphics rendering of a web page.
  • The new version of Web Expressions was released to day and it includes a Super Preview to compare what you design pages in to different browser versions such as IE 6, 7, 8, Firefox, and new with this release is Safari on the Mac. Yes you can now test Mac versions of Safari with needing a Mac. By they way, you can also do it on Spoon.net. http://spoon.net/browsers/

There a few other announcement but those were the ones as a web developer that interested me. I will try and update the blog with other stuff I learn through out this week so stay in touched.

 



Off to Microsoft TechEd

clock June 4, 2010 07:32 by author Steve

Next week is TechEd and I am fortunate that my work will be sending me there with the expectation that I come back with a lot of notes.

With that in mind, I am going to try and update my blog with a summary of that days sessions, so if you are not going and would like to read about what's going on, come on back and take gander this blog and check my summaries of each the sessions I plan on attending.

Below is what I am planning on attending:

 

Monday, June 7
 
Hall F
KEY01 Tech·Ed North America Keynote Presentation 11:00 AM1:00 PM

Rm 383
DEV324 Data Development GPS: Guidance for Choosing the Right Data Access Technology for Your Application Today
2:15 PM
Rm 356
WEB316 What’s New in Microsoft ASP.NET MVC 2 2:45 PM4:00 PM
Rm 388
WEB308 My Web Site Is So Slow...and I Don’t Know What to Do about It! 4:30 PM5:45 PM
Rm 272
WEB204 Microsoft Visual Studio 2010 for Web Deployment
5:45 PM
Rm 287
WEB309 Practical Strategies for Debugging Cross-Browser Display Issues 5:45 PM9:00 PM
 
Tuesday, June 8

WEB302 A Lap around Windows Internet Explorer 9 for Developers
11:15 AM
Auditorium B
KEY02 Business Intelligence Conference Keynote Presentation
11:00 AM
Rm 355
BOF06-DV Microsoft ASP.NET MVC: Share Your Stories from the Trenches 11:00 AM1:30 PM

Rm 387
WEB202 Building Web Sites Using the Orchard Content Management System (CMS) 3:15 PM4:30 PM
Rm 391
WEB206 Microsoft ASP.NET MVC for Web Form Programmers
4:30 PM
Rm 398
ASI204 Windows Azure AppFabric Overview 5:00 PM6:15 PM
Rm 281
COS305 Microsoft SQL Azure Development Best Practices 6:00 PM9:00 PM
 
Wednesday, June 9


WEB307 Effective RIA: Tips and Tricks for Building Effective Rich Internet Applications
11:00 AM
Rm 398
ASI313 Windows Server AppFabric Caching: What It Is and When You Should Use It 11:00 AM1:30 PM
 
Lunch 11:45 AM1:00 PM
Rm 388
WEB301 10 Ways to Protect Users of Your Web Applications
1:00 PM
Rm 265
COS208 Building Engaging Apps with Data Using Microsoft Codename “Dallas”
1:00 PM
Rm 276
ASI312 What's New in Windows Communication Foundation in .NET Framework 4 1:30 PM2:45 PM
Rm 350
WEB02-INT Extending Microsoft ASP.NET MVC 2
2:45 PM
Rm 272
ARC303 How Frameworks Can Kill Your Projects, and Patterns Can Prevent You from Getting Killed
2:45 PM
Auditorium B
DEV205 Overview of the Microsoft ADO.NET Entity Framework 4.0 3:15 PM4:30 PM
Rm 283
DEV303 Building RESTful Applications with the Open Data Protocol
4:30 PM
Rm 287
DPR306 Metrics That Matter: Real Measures to Improve Software Development 5:00 PM6:15 PM
Rm 288
DEV308 Heterogeneous Development with Microsoft Visual Studio 2010 Team Foundation Server 6:00 PM9:00 PM
 
Thursday, June 10

Rm 293
DEV317 Profiling and Debugging Parallel Code with Microsoft Visual Studio 2010 9:45 AM11:00 AM
Rm 398
WEB303 Administering Sites That Scale Using Internet Information Services (IIS) 7.5, ARR and URL Rewrite 11:00 AM1:30 PM

Rm 356
DPR302 Behavior-Driven Development in the Real World
2:45 PM
Auditorium A
DEV305 Deep Dive into Microsoft ADO.NET Entity Framework 3:15 PM4:30 PM
Auditorium B
WSV401 Advanced Automation Using Windows PowerShell 2.0
4:30 PM
Rm 398
ASI308 Programming AppFabric: Moving Microsoft .NET to the Cloud 5:00 PM6:15 PM
Rm 291
DPR303 Branching and Merging Practices 6:30 PM11:00 PM

 

 



JQuery, Asp.Net MVC 2 Multi Project Areas and Other News Minutia

clock April 3, 2010 08:45 by author Steve

jQuery News

I know this nugget is a couple of weeks old now, but did anyone catch the news that Microsoft is throwing its support behind jQuery?

So it seems that if you have been using the Microsoft AJAX tools you are probably not going to be seeing much of an effort to improve those tools in the future. Not that it really matters, since it seems that most developers have abandon that toolset about a year ago, and with the emergance of MVC, they were becoming irrelevant anyway. Also, the earlier versions of the Microsoft AJax framework had performance problems under heavy load and although they have done a lot of work to make improvements, jQuery is still far and away much faster. Plus, when working with designers who are not Microsoft centric, jQuery built a bridge for the developer and designer to work together.

I have several examples on jQuery Ajax calls in case you are interested.

My first official large site using ASP.Net MVC 2

So this past month I started working on my first large MVC web application using MVC 2, and although I have been playing around with for more than a year now, I have learned a lot in the few months. The book that was really helpful was “Pro ASP.Net MVC” Framework by Steven Sanderson. I highly recommend it if you are getting started, but you might want to wait until the MVC 2 revision comes out. If you can't wait for the revision there is the eBook "Asp.Net MVC 2 In Action." This book is good in that it covers some more advanced topics like how to keep you controllers light. I think the two books together will get you well on the way to developing in ASP.Net MVC.

So far the only hang up I had was that I had set up my solution to incorporate multi project areas which was supported in the MVC 2 preview releases of Areas. However, when the RTM came out it was no longer supported. I searched and searched for solutions to my dilemma, but the only thing I could find was post by Jonathon who basically had the same experience I had, and a reference to an obscure message on a message board saying (by what appeared to be some one from the ASP Team) that it was not supported. To date, I haven't found any more formal post or article saying that was not the case.

I looked at trying the MvcContrib’s portable area alternative, and it’s a pretty nice approach, but I would like my views deployed to production as separate files and not as a resource file in a assembly, so I decided not go that route. I think for now, I am just going to include the areas in a single project and when the next version of MVC comes out—pull the different areas out into different projects then—if that is, they will have that feature in future releases.

TFS license for VS 2008

I heard this week, not from someone official, that once Visual Studio 2010 is released, they will also include Team Foundation Server for Visual Studio 2008 as a part of the MSDN license. That good news for me as I have been using the trial version for the past few weeks. I suppose the cool tool now is GIT so maybe I should take a look at that as well. At least for my VS 2010 stuff. My only thing is I am getting kind of tired of having to learn a new source control repository every year, there are other cooler things I could be learning, but I guess that is part of the job.



MVC 2 Strongly Typed HTML Helper and Enhanced Validation Sample

clock March 13, 2010 09:40 by author Steve

In lue of the off the official release of ASP.NET MVC 2 RTM, I decided I would put together a quick sample of the enhanced HTML.Helpers and validation controls.

I am going to use my sample event site where I will have a form so a user can search for information about a certain events. So when the Search page loads the Search action is fired return my strongly typed model. to the view.

   1: [HttpGet]
   2: public ViewResult Search(): public ViewResult Search()
   3: {
   4:     IList<EventsModel> result = _eventsService.GetEventList();
   5:     var viewModel = new EventSearchModel
   6:                         {
   7:                             EventList = new SelectList(result, "EventCode","EventName","Select Event")
   8:                         };
   9:     return View(viewModel);
  10: }

Nothing special here, although I did want to show how to load up a strongly typed drop down list because that hung me up for a little bit. So to that, I am going to pass back a SelectList to the view and my HTML helper should no how to load this.

So lets take a look at the mark up for the view.

   1: <%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" 
   2: Inherits="System.Web.Mvc.ViewPage<EventsSample.Models.EventSearchModel>" %>
   3:  
   4: <asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
   5:     Search
   6: </asp:Content>
   7:  
   8: <asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
   9:  
  10:     <h2>Search for Events</h2>
  11:  
  12:     <% using (Html.BeginForm("Search","Events")) {%>
  13:         <%= Html.ValidationSummary(true) %>
  14:         
  15:         <fieldset>
  16:             <legend>Fields</legend>
  17:             
  18:             <div class="editor-label">
  19:                 <%= Html.LabelFor(model => model.EventNumber) %>
  20:             </div>
  21:             <div class="editor-field">
  22:                 <%= Html.TextBoxFor(model => model.EventNumber) %>
  23:                 <%= Html.ValidationMessageFor(model => model.EventNumber) %>
  24:             </div>
  25:             
  26:             <div class="editor-label">
  27:                 <%= Html.LabelFor(model => model.GuestLastName) %>
  28:             </div>
  29:             <div class="editor-field">
  30:                 <%= Html.TextBoxFor(model => model.GuestLastName) %>
  31:                 <%= Html.ValidationMessageFor(model => model.GuestLastName) %>
  32:             </div>
  33:             
  34:             <div class="editor-label">
  35:                 <%= Html.LabelFor(model => model.EventName) %>
  36:             </div>
  37:             <div class="editor-field">
  38:                 <%= Html.DropDownListFor(model => model.EventName, Model.EventList,"Select Event") %>
  39:                 <%= Html.ValidationMessageFor(model => model.EventName) %>
  40:             </div>
  41:             
  42:             <p>
  43:                 <input type="submit" value="Save" />
  44:             </p>
  45:         </fieldset>
  46:  
  47:     <% } %>
  48:  
  49:     <div>
  50:         <%= Html.ActionLink("Back to List", "Index") %>
  51:     </div>
  52:  
  53: </asp:Content>

 

A nice feature is the scaffolding that MVC has to generate code. I simply right clicked inside my Search() action, inside the EventsController and selected “Add View” and then I selected my strongly typed object that I wanted to pass to the view and also selected that I wanted the content type be “Edit”. With that the aspx page was completely generated, although I did have to go back in and change the textbox for the Event Names to a drop down list of the names to select from.

The new feature with MVC 2 are the strongly typed HTML helpers. So now, my textboxes, drop down list, and validation helpers are all strongly typed to my model.  This features gives you the benefits of intellisense and also makes it easier to debug. “The Gu” has a great post about the feature in case you want more details. The DropDownListFor function to generate the drop down list was a little tricky for me. You first need to use a Lanbda expression to pass in the property you want the selected value assigned to in your model, and then you need to pass in the list directly from the model.

Validations

To validate the form, you can use the strongly type validation HTML helpers which will inspect your model and return errors if the validation fails. The definitions of these rules are set directly on the Model itself so lets take a look.

   1: using System.ComponentModel.DataAnnotations;
   2: using System.Web.Mvc;
   3:  
   4: namespace EventsSample.Models
   5: {
   6:     public class EventSearchModel
   7:     {
   8:         [Required(ErrorMessage = "Please enter the event number.")]
   9:         [RegularExpression(@"\w{6}", 
  10:             ErrorMessage = "The Event Number must be 6 letters and/or numbers.")]
  11:         public string EventNumber { get; set; }
  12:  
  13:         [Required(ErrorMessage = "Please enter the guest's last name.")]
  14:         [RegularExpression(@"^[A-Za-zÀ-ÖØ-öø-ÿ1-9 '\-\.]{1,22}$", 
  15:             ErrorMessage = "The gueest's last name must 1 to 20 characters.")]
  16:         public string GuestLastName { get; set; }
  17:  
  18:         public string EventName { get; set; }
  19:         public SelectList EventList { get; set; }
  20:     }
  21: }

Pretty cool!

Okay, the only thing left to do is perform the validation in the POST action.

   1: [HttpPost]
   2: public ViewResult Search(EventSearchModel eventSearchModel)
   3: {
   4:     if (ModelState.IsValid) return View("SearchResults");
   5:     else
   6:     {
   7:          IList<EventsModel> result = _eventsService.GetEventList();
   8:         eventSearchModel.EventList = new SelectList(result, "EVentCode","EventName");
   9:  
  10:         return View(eventSearchModel);
  11:     }
  12: }
  13:     }

 

If the form entries are valid, here I am simply displaying the SearchResult, but in a real world sample I would also go out get the results first. You get the idea though. In my case, when the form is not valid, I also had to reload my SelectList with the event names before I loaded the page again. Remember this is MVC, no _VieState here :)

So that’s it. Now my form is validating the data and when it fails it looks like this.

response



Build a REST Web Application with WCF and jQuery

clock February 20, 2010 09:05 by author Steve

Introduction

So at my work, we started on a new web application, and mainly because a lot of guys working on it were going to be new and also because it is somewhat a visible project; we figured we would keep the risk low and use the traditional web forms ASP.Net application.

On the other hand we still wanted the separation of concerns you get from a MVC style application, and because we were also planming on using designers for the web pages who were very proficient with jQuery but who did not know much about ASP.net. As a matter of fact, most of these guys write jQuery and HTML with a simple text editor…show offs :)

Also, for performance reasons and the fact the web designers were very familiar with the protocol, we wanted to pass JSON objects back and forth from the client to the server and vice versa.

Another goal is we want to keep as little as code as possible in the web project and place it in a different “Core” assembly. This would make deployments for us easier.

The Solution Layout

The solution looks like this:

The EventList.aspx page will be the page I will use for this demo. I deleted the associated code-behind files with and also removed the references of the code-behind from the page deplaration.

When I added the EventService.svc WCF Service into the project, Visual Studio added the EventService.svc.cs file and the IEventService service contract interface. I moved them to the Core project and changed the namespaces.

I also added a folder for the Unity service factory build up. You can see how I did it in a previous post.

The Service

Since I moved the associated files that were added when I added the WCF Service, I have to go in and change the declarations so they point to the proper place.

   1: <%@ ServiceHost 
   2:     Language="C#" 
   3:     Debug="true" 
   4:     Service="RestSample.Core.ServiceContracts.EventsService" 
   5:     Factory="RestSample.Core.ServiceContrainer.UnityServiceHostFactory" 
   6: %>

 

Also the code behind reference was moved and Factory attribute was added to point to my custom Unity Service Host Factory.

The Service Contract

The Service contract needs to be decorated with the ServiceContract attrubute; but I also need to specify that this message will take “POST” requests, and that the protocal will be JSON.

   1: using System.ServiceModel;
   2: using System.ServiceModel.Web;
   3: using RestSample.Core.DataContracts;
   4:  
   5: namespace RestSample.Core.ServiceContracts
   6: {
   7:     [ServiceContract]
   8:     public interface IEventsService
   9:     {
  10:         [OperationContract]
  11:         [WebInvoke(Method = "POST",
  12:             ResponseFormat = WebMessageFormat.Json,
  13:             BodyStyle = WebMessageBodyStyle.Bare)]
  14:         EventList GetLatestEvents();
  15:     }
  16: }

 

The implantation of this contract is injected with my controller where my response will be built up.

Here is the service contract implementation:

   1: using RestSample.Core.Controllers;
   2: using RestSample.Core.DataContracts;
   3:  
   4: namespace RestSample.Core.ServiceContracts
   5: {
   6:     public class EventsService : IEventsService
   7:     {
   8:         private readonly IEventController _eventController;
   9:  
  10:         public EventsService(IEventController eventController)
  11:         {
  12:             _eventController = eventController;
  13:         }
  14:  
  15:         #region IEventsService Members
  16:  
  17:         public EventList GetLatestEvents()
  18:         {
  19:             return _eventController.GetLatestEvents();
  20:         }
  21:  
  22:         #endregion
  23:     }
  24: }

 

Here is the controller class implementation:

   1: using System;
   2: using System.Collections.Generic;
   3: using RestSample.Core.DataContracts;
   4:  
   5: namespace RestSample.Core.Controllers
   6: {
   7:     public class EventController : IEventController
   8:     {
   9:         #region IEventController Members
  10:  
  11:         public EventList GetLatestEvents()
  12:         {
  13:             var list = new EventList {Items = new List<EventItem>()};
  14:             const int upper = 5;
  15:             for (int i = 0; i < upper; i++)
  16:             {
  17:                 list.Items.Add(new EventItem
  18:                                    {
  19:                                        EventCode = i.ToString(),
  20:                                        EventDate = DateTime.Today.AddDays(-1*i).ToLongDateString(),
  21:                                        EventName = string.Format("Name {0}", i)
  22:                                    });
  23:             }
  24:  
  25:             return list;
  26:         }
  27:  
  28:         #endregion
  29:     }
  30: }

Obviously I am just returning back trash, but you get the point. Here are the data contracts:

   1: using System.Runtime.Serialization;
   2:  
   3: namespace RestSample.Core.DataContracts
   4: {
   5:     [DataContract]
   6:     public class EventItem
   7:     {
   8:         [DataMember]
   9:         public string EventCode { get; set; }
  10:         [DataMember]
  11:         public string EventName { get; set; }
  12:         [DataMember]
  13:         public string EventDate { get; set; }
  14:     }
  15: }

 

   1: using System.Collections.Generic;
   2: using System.Runtime.Serialization;
   3:  
   4: namespace RestSample.Core.DataContracts
   5: {
   6:     [DataContract]
   7:     public class EventList
   8:     {
   9:         [DataMember]
  10:         public IList<EventItem> Items { get; set; }
  11:     }
  12: }

 

The web.config Set Up.

Because I want to return JSON, and because I moved the service files; I need to make some changes to the System.ServiceModel section of the web.config.

   1: <system.serviceModel>
   2:     <behaviors>
   3:         <serviceBehaviors>
   4:             <behavior name="RestSample.Core.ServiceContracts.EventsServiceBehavior">
   5:                 <serviceMetadata httpGetEnabled="true"/>
   6:                 <serviceDebug includeExceptionDetailInFaults="false"/>
   7:             </behavior>
   8:         </serviceBehaviors>
   9:   <endpointBehaviors>
  10:     <behavior name="WebHttpBehavior">
  11:       <webHttp />
  12:     </behavior>
  13:   </endpointBehaviors>
  14:     </behaviors>
  15:     <services>
  16:         <service behaviorConfiguration="RestSample.Core.ServiceContracts.EventsServiceBehavior" name="RestSample.Core.ServiceContracts.EventsService">
  17:             <endpoint address="" binding="webHttpBinding" contract="RestSample.Core.ServiceContracts.IEventsService" behaviorConfiguration="WebHttpBehavior">
  18:                 <identity>
  19:                     <dns value="localhost"/>
  20:                 </identity>
  21:             </endpoint>
  22:             <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
  23:         </service>
  24:     </services>
  25: </system.serviceModel>

I added an Endpoint Behavior and specified webHttp and then referenced it in the endpoint. This enables the “web programming model” for WCF which makes the service RESTful.

I also changed the name and contract location of the service so it points to new location in my solution.

Now my service is ready and if I run the service file at this point I get the standard service page to come up to show the everything is configured properly.

The Client

Now that the service is working I am just going to write some jQuery to make a call to the service when a button is click.

Here is the aspx page.

   1: <%@ Page Title="" Language="C#" MasterPageFile="~/Shared/Main.Master" %>
   2: <asp:Content ID="Content1" ContentPlaceHolderID="head" runat="server">
   3:     <script src="../Scripts/json2.js" type="text/javascript"></script>
   4:     <script src="../Scripts/restsample.js" type="text/javascript"></script>
   5: </asp:Content>
   6: <asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="server">
   7:     
   8:     <input type="button" value="Make Call" id="restCall" />
   9: </asp:Content>

Here is the jQuery

   1:  
   2: $(document).ready(function() {
   3:     setInputFunction();
   4: });
   5:  
   6: function setInputFunction() {
   7:     $('input').click(function() {
   8:         makeEventCall();
   9:     });
  10: }
  11:  
  12: function makeEventCall() {
  13:     $.ajax({
  14:         url: 'http://localhost:56296/Services/EventsService.svc/GetLatestEvents',
  15:         type: "POST",
  16:         processData: false,
  17:         contentType: "application/json",
  18:         timeout: 10000,
  19:         dataType: "text",  // not "json" we'll parse
  20:         success: function(data) {
  21:             loadSuccessful(data);
  22:         }
  23:     });
  24: }
  25:  
  26: function loadSuccessful(data) {
  27:     var result = JSON.parse(data);
  28:     console.log('result', result);
  29: }
  30:  
  31:  

So the jQuery code above makes a call to the service when the button is clicked. Here are some things to notice about this jQuery code.

  • First off, you cannot see it here but I have a script reference to the jQuery 1.4.1 file located on the Microsoft CDN. More on that here.
  • The url is the a combination of the service url and the function GetLatestEvents.
  • I need to specify “POST” as the type because that is what I specified on my ServiceContract.
  • I am going to return back text and then parse it using Douglas Crockford's json2.js.
  • For this demo, I am just going to log the response to the Firebug console using the console.log feature. (Note: remember to take this out later because you will get a JavaScript error in other browsers).

So with I am done and now when I bring up that web page and click the button I get this JSON response back.

{"Items":[{"EventCode":"0","EventDate":"Saturday, February 20, 2010","EventName":"Name 0"},
{"EventCode"
:"1","EventDate":"Friday, February 19, 2010","EventName":"Name 1"},
{"EventCode":"2","EventDate":"Thursday
, February 18, 2010","EventName":"Name 2"},
{"EventCode":"3","EventDate":"Wednesday, February 17, 2010"
,"EventName":"Name 3"},
{"EventCode":"4","EventDate":"Tuesday, February 16, 2010","EventName":"Name 4"
}]}

The response in Firebug looks like this:

response

 

Hope that helps :)



Blog Site Updated

clock February 13, 2010 11:23 by author Steve

I just updated my blog with the latest version of BlogEngine.Net version 1.6. You can get the latest downloads here.

Also, I updated my theme to Indigo.  I think it is a really nice look if I do say so myself. You can get a bunch of themes here (click on the theme pack link), and if you want to see a screencast on how to update you theme you can check it out here.

The guys at BlogEngine.Net have done really nice job with this application. I have been using it since the 1.1 version many years ago, and have been really happy with that they have done. As you can see from previous posts, I have been going though their site and seeing if I could convert it to MVC. I don’t actually plan on using that version, but I must say I am learning a lot not only about writing good code, but also about how blogging sites work in general.

Anyways, if you need a .Net blog site; BlogEngine.Net gets a thumbs up from me.



Spark View Engine – Render Partial While Passing the Model

clock January 5, 2010 15:31 by author steve

Just a quick follow up on my previous post specifically about rendering partial views using the Spark View Engine.  If you want to use a partial view and you also want to pass it a model, you just create parameter and pass the model in that parameter.

 

As I stated, the convention for the shared content is to create a file in the “Shared” view directory and prefix the file with the “_”.

 

For example:

I have created a post list partial file and I am going to call it from my “Index” view in the “Home” folder.

renderpartialsamp1

 

In the HomeController class, the Index action is just returning 10 items in a IList collection.

   1: public ActionResult Index()
   2: {
   3:     IList<PostDto> items = _postService.GetMostRecentPosts();
   4:  
   5:     ViewData["BasicPosts"] = items;
   6:     return View();
   7: }

Next, my Index view passes the collection of posts to the partial control.  The Index.spark file has the following code.

   1: <viewdata BasicPosts="IList<PostDto>">
   2:  
   3:  
   4: <postList posts="BasicPosts" />

 

Now the model is in the partial file and I can do with it what ever I want. In this example, the _postList.spark file has the following code that loops through the collection of posts and displays the “Title”.

   1: <ul>
   2: <for each="var post in posts">
   3:     <li>${post.Title}</li>
   4: </for>
   5: </ul>

 

The above sample produces this partial view.

partialResult



Building an List of Links Asynchronously Using jQuery, AJAX, PURE, and Spark View Engine for MVC

clock December 27, 2009 13:05 by author steve

Yes, I know the title is a mouthful, but its all the cool stuff I used to make this trick work.  I have mentioned before that I have been using the Spark View Engine with ASP.Net MVC just because I think it is much cleaner markup when it comes to intermingling HTML with C#.  I also mentioned that I have been working on my blog app and like my own home blog page, I want to have a blog roll.  So what I did was create a table with two records containing information about my two favorite blogs.

blog_table

Now what I want to do is on the Master Page that I am using is have to these two links display on the page asynchronously after the base HTML loads.

The Spark Master Page and Partial Rendering

There is pretty good documentation for Spark for getting started, so I won’t go into detail about it here; but there are a few things I wanted to mention.  The default way to use a Master Page in the Spark View Engine is to create a folder named “Layouts” inside the “View” folder and then to add a file named “Application.spark” in that folder.  This is the convention that will allow all other views to access that Master Page unless otherwise specified.

   1: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
   2: <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
   3:   <head>
   4:     <title>${H(Title)}</title>
   5:     <link rel="stylesheet" href="~/Content/Site.css" type="text/css" />
   6:     <use content="head"/>
   7:      <script src="http://ajax.microsoft.com/ajax/jquery/jquery-1.3.2.min-vsdoc.js" type="text/javascript"></script>
   8:     <script src="http://ajax.microsoft.com/ajax/jquery/jquery-1.3.2.min.js" type="text/javascript"></script>
   9:     <script src="/Scripts/pure.js" type="text/javascript"></script>
  10:   </head>
  11:   <body>
  12:     <div id="wrapper">
  13:         <div id="header">
  14:             <div id="logo">
  15:                 <h1>Website Logo Goes Here</h1>
  16:             </div>
  17:             <div id="search">
  18:                 Search goes here
  19:             </div>
  20:         </div>
  21:         <div id="header_menu">
  22:             <ul id="menu">
  23:                 <li>
  24:                     <a title="" accesskey="1" href="#">Home</a>
  25:                 </li>
  26:                 <li>
  27:                     <span>|</span>
  28:                 </li>
  29:                 <li>
  30:                     <a title="" accesskey="2" href="#">Blog</a>
  31:                 </li>
  32:                 <li>
  33:                     <span>|</span>
  34:                 </li>
  35:                 <li>
  36:                     <a title="" accesskey="3" href="#">About Me</a>
  37:                 </li>
  38:                 <li>
  39:                     <span>|</span>
  40:                 </li>
  41:                 <li>
  42:                     <a title="" accesskey="4" href="#">Contact</a>
  43:                 </li>
  44:             </ul>
  45:             <div id="menu_spacer">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
  46:             </div>
  47:         </div>
  48:         <div id="content">
  49:             <div id="colOne">
  50:                 <div class="box">
  51:                      
  52:                     <myLinks />
  53:                 </div>
  54:             </div>
  55:             <div id="colTwo">
  56:                 <use content="view"/>
  57:             </div>
  58:         </div>
  59:         
  60:     
  61:   </body>
  62: </html>

Some things to notice on the master page here, is that I am accessing jQuery, and PURE.  Of course, jQuery is the JavaScript framework that makes almost everything JavaScript related really easy.  The other script tag for PURE is also a JavaScript framework but it is mainly to make the mapping of markup to your JSON response much easier.  We use it a lot where I work, so I have become a big fan of it.  I will demonstrate that later.

Also another thing to notice in this code is the tag <myLinks />.  This is how Spark does partial HTML rendering.  The convention for partial rendering in Spark is to create a file in the “Views/Shared” folder that is prefixed with “_” and has the extension “spark” like all the other views.  So for my example above, I have a file located at “<project_location>/View/Shared/_myLinks.spark”.

 

The Controller Class

Nothing special here. I have a controller class that returns a JSON response.  The only thing I should mention though is in order for PURE to work with a list of records you will need to rap your List object in another object.  Also, as mentioned in a previous post, I need to return a JsonResult to get the properly formatted response.  Since these links won’t change much (I am not that fickle) I am caching this action using the OutputCache attribute.

   1: using System.Collections.Generic;
   2: using System.Web.Mvc;
   3: using Aviblog.Core.Dto;
   4: using Aviblog.Core.Services;
   5:  
   6: namespace Aviblog.Web.Controllers
   7: {
   8:     public class LinksController : Controller
   9:     {
  10:         private readonly ILinksService _linksService;
  11:  
  12:         public LinksController(ILinksService linksService)
  13:         {
  14:             _linksService = linksService;
  15:         }
  16:  
  17:         [AcceptVerbs(HttpVerbs.Get)]
  18:         [OutputCache(Duration = 60, VaryByParam = "None")]
  19:         public JsonResult All()
  20:         {
  21:             Links links;
  22:             IList<LinkDto> result = _linksService.GetActiveLinks();
  23:             links = result != null ? new Links() {LinkList = result} : null;
  24:             return Json(links);
  25:         }
  26:     }
  27: }

My Links class looks like this:

   1: using System.Collections.Generic;
   2:  
   3: namespace Aviblog.Core.Dto
   4: {
   5:     public class Links
   6:     {
   7:         public IList<LinkDto> LinkList { get; set; }
   8:     }
   9: }

This will generate a JSON response as follows:

{"LinkList":
[{"LinkId":1,"Title":"Scott Gunthie","Description":"Scott Gunthrie\u0027s Blog","BlogUri":http://weblogs.asp.net/scuttgu/,
"FeedUri":null,"IsActive":true},{"LinkId":2,"Title":"Scott Hanselman",
"Description":"Scott Hanselman\u0027s Blog","BlogUri":"http://www.hansleman.com/","FeedUri":null,"IsActive":true}]}

Notice, that I now have my wrapper class called LinkList that I can use to tell PURE that this is my collection.

 

The Partial HTML that Loads the Links

So in my _myLinks.spark file I have the JavaScript that is going to make an AJAX call to get the links, and the PURE code that will map the response back to the unordered list.

   1: <script type="text/javascript">
   1:  
   2:     $(document).ready(function() {
   3:         $.ajax({
   4:             type: "GET",
   5:             url: "/Links/All",
   6:             dataType: "json",
   7:             success: function(res) {
   8:                 var $blogRollList = $("ul#blogRollList");
   9:                 
  10:                 var directive = {
  11:                     'li':{
  12:                         'link<-LinkList':{
  13:                             'a':'link.Title',
  14:                             'a@href':'link.BlogUri'
  15:                         }
  16:                     }
  17:                 };
  18:                 
  19:                  $blogRollList.render(res, directive);
  20:  
  21:             }
  22:         });
  23:     });
</script>
   2:  
   3:         
   4: <h3>Bloggroll</h3>
   5: <div id="blogRoll">
   6:     <ul id="blogRollList">
   7:         <li><a></a></li>
   8:     </ul>
   9: </div>

I am using the $.Ajax function to make a call out to my controller class “LinksController” and the action “All”.  If the code returns a successful response, the PURE code maps the response to the list.

The $blogRollList variable is the ul tag that I want my response to be loaded into.

The directive variable is how I tell PURE to map my response.  It is saying for each item in the response, create a list tag.  The “link<-LinkList” is saying for the collection LinkList there will be items named “link”.  Inside that declaration I am then using each “link” item that was defined and them mapping it to an anchor tag.

The Result

So now when the page loads I get the result:

blogroll



Calendar

<<  September 2010  >>
MoTuWeThFrSaSu
303112345
6789101112
13141516171819
20212223242526
27282930123
45678910

View posts in large calendar

Sign in