Steve Moseley

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

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



Syndicating RSS in an ASP.Net MVC app using WCF

clock December 15, 2009 15:26 by author steve

About a month back Rob Conery mentioned that he was going to create a blogging application using MVC, which caused me to think to myself: “SELF! why don’t you try something like that and see what you can come up with?”  So in my spare time when I am not doing real work or at home shuttling kids around, I’ve been playing around with this idea.  I am really happy with my BlogEngine.Net set up and probably will continue to use it even if I were to finish this app but I figure this would be an opportunity to just do something different than I have been doing lately and learn some new things that I have not had a chance to work with as of yet.

So with that in mind, one of the first things I decided to tackle was going about syndicating an RSS feed and as it turns out it is not too terribly difficult to do; although, there are some things I did struggle with—uhhh---but I am getting ahead of myself.

Build you own ActionResult

I mention in my previous post that ASP.Net come with several different controller actions, and the one that I used in the that example was the JsonResult.  Well JsonResult really is just a class that is derived from the abstract class ActionResult.  I can write my own class that derives from ActionResult to return back to the view an RSS feed which is what I am going to do in this example.

   1: using System.ServiceModel.Syndication;
   2: using System.Web.Mvc;
   3: using System.Xml;
   4:  
   5: namespace Aviblog.Core.ActionResults
   6: {
   7:     public class RssResult : ActionResult
   8:     {
   9:         private readonly SyndicationFeed _feed;
  10:  
  11:         public RssResult(SyndicationFeed feed)
  12:         {
  13:             _feed = feed;
  14:         }
  15:  
  16:         public override void ExecuteResult(ControllerContext context)
  17:         {
  18:             context.HttpContext.Response.ContentType = "application/rss+xml";
  19:             var formatter = new Rss20FeedFormatter(_feed);
  20:  
  21:             using (XmlWriter writer = XmlWriter.Create(context.HttpContext.Response.Output))
  22:                 if (writer != null) formatter.WriteTo(writer);
  23:         }
  24:     }
  25: }

So in my custom RssResult that inherits from ActionResult, I need to then override the ExecuteResult method.  Inside that method I then need to set the response type to “application/rss+xml” so it can be rendered as RSS.  The next thing to notice is that in my constructor I am passing in an object of type SyndicationFeed which is a part of WCF.  It is in the System.ServiceModel.Syndication namespace.  You can find it by referencing the System.ServiceModel.Web assembly.  I can then use the Rss20FeedFormatter to generate XML which is RSS compliant.

 

Building the SyndicationFeed

Building the SyndicationFeed object is where I had the most trouble. If you just want a simple compliant RSS feed, this guy works great; however, as you can see just from looking at my own RSS feed there many other elements you can extend to an RSS feed and adding those to the SyndicationFeed element is a bit tricky.

   1: public SyndicationFeed Buildfeed()
   2:         {
   3:             var settingQry = _settingsRepository.GetSettings();
   4:             const string nameKey = "name";
   5:             const string nameDescription = "description";
   6:             const string link = "link";
   7:             string blogTitle = _settingsService.GetValue(settingQry, nameKey);
   8:             string blogDescription = _settingsService.GetValue(settingQry, nameDescription);
   9:             Uri blogUrl = _settingsService.GetUri(settingQry, link);
  10:  
  11:             var feed = new SyndicationFeed(blogTitle, blogDescription, blogUrl);
  12:  
  13:             foreach (var element in _feedRepository.GetFeedElements())
  14:                 feed.ElementExtensions.Add(BuildXmlElement(element));
  15:  
  16:             feed.Items = LoadPosts(_postService.GetMostRecentPosts());
  17:             return feed;
  18:         }
  19:  
  20:         private static XmlElement BuildXmlElement(FeedElementDto element)
  21:         {
  22:             var doc = new XmlDocument();
  23:             XmlElement feedElement = doc.CreateElement(element.Prefix, element.Element, element.Namespace);
  24:             feedElement.InnerText = element.InnerText;
  25:             return feedElement;
  26:         }

From the code you can see that when I am instantiating the SyndicationFeed object I am passing in the title of the blog, the blog description, and the URL.  Where it got a bit hairy, was adding other elements that prefixed a common namespace.  I could add the namespace for each element (as seen in the code) but there does not seem to be a way to put the common namespaces in say the channel element and then just use the prefix to those namespaces later. I ended up having to repeat the same namespaces over again.  But that being said, it is still pretty easy to build the feed.

Once the feed object is ready I then could add each of the posts by mapping them to a SyndicationItem object and then add those collection of objects to the items collection in the feed.

   1: private static IEnumerable<SyndicationItem> LoadPosts(IEnumerable<PostDto> posts)
   2:         {
   3:             IList<SyndicationItem> items = new List<SyndicationItem>();
   4:             foreach (var post in posts)
   5:             {
   6:                 var item = new SyndicationItem();
   7:                 item.Title = new TextSyndicationContent(post.Title);
   8:                 item.Authors.Add(new SyndicationPerson(post.Author));
   9:                 item.Content = SyndicationContent.CreateHtmlContent(post.PostContent);
  10:                 items.Add(item);
  11:             }
  12:             return items;
  13:         }

 

The Controller Class

Now that I have my RssResult and my functionality to build the SyndicationFeed object, I can then create an action inside my controller class that puts the two together.

   1: public class SyndicationController : Controller
   2:     {
   3:         private readonly IRss20SyndicationService _rss20SyndicationService;
   4:  
   5:         public SyndicationController(IRss20SyndicationService rss20SyndicationService)
   6:         {
   7:             _rss20SyndicationService = rss20SyndicationService;
   8:         }
   9:  
  10:         public RssResult Rss()
  11:         {
  12:  
  13:             return new RssResult(_rss20SyndicationService.Buildfeed());
  14:         }
  15:     }

 

The Result

So when I browse to domain/controller/action in this case http://localhost:64533/Syndication/Rss I get the following RSS sample:

 

   1: <?xml version="1.0" encoding="utf-8"?>
   2: <rss xmlns:a10="http://www.w3.org/2005/Atom" version="2.0">
   3:   <channel>
   4:     <title>Steve Moseley</title>
   5:     <link>http://www.test.com/</link>
   6:     <description>Trying my best to apprehend all these dev changes.</description>
   7:     <blogChannel:blogRoll xmlns:blogChannel="http://backend.userland.com/blogChannelModule">http://www.avingtonsolutions.com/blog/opml.axd</blogChannel:blogRoll>
   8:     <blogChannel:blink xmlns:blogChannel="http://backend.userland.com/blogChannelModule">http://www.dotnetblogengine.net/syndication.axd</blogChannel:blink>
   9:     <dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Steve Moseley</dc:creator>
  10:     <dc:title xmlns:dc="http://purl.org/dc/elements/1.1/">Steve Moseley</dc:title>
  11:     <geo:lat xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#">0.000000</geo:lat>
  12:     <geo:long xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#">0.000000</geo:long>
  13:     <item>
  14:       <author>Steve</author>
  15:       <title />
  16:       <description>
  17:        blah, blah, blah
  18:       </description>
  19:     </item>
  20:   </channel>
  21: </rss>

 

Looks pretty good, although, if you look at my actual RSS feed and this one, you will notice that the name spaces are repeated verses being listed at the top as they probably should be.  I need to play around with it some more but this gets the job done and I did not have to write all that much code, which is nice.



Filtering Dropdowns in a ASP.Net MVC App using jQuery and jSon.

clock October 24, 2009 14:39 by author steve

I have often come across the need to load a dropdown list based on the selection of another drop down list on a form.  In web forms it is really easy, especially if you were just doing a regular page post back.  You simply set the dropdown’s AutoPostBack property to true and then on the change event load the second dropdown based on the value of the first event.

Then along came the Ajax Toolkit that had Ajax server controls that would basically do that for you pretty simply without a full page postback.  You could see a demo of that functionality here.

How to do this with MVC

Now in MVC all the cool server controls are gone but with just a little extra work we can get the same functionality pretty easily.  Moreover, using the Json protocol makes the population of the second drop down much lighter accross the wire.

In my example, I have a pretend scenario where the user selects an event from the first drop down and based on the value of the first selection, the options of the second is dropdown is populated.

Here is the view code I am using for this example. (Note: I am using the Sparks View Engine for the View Framework instead of the Microsoft MVC View Framework because it makes the mark up much cleaner.

   1: <viewdata EventList="SelectList" />
   2:  
   3:  
   4: <content name="head">
   5:     <script src="http://ajax.microsoft.com/ajax/jquery/jquery-1.3.2.min-vsdoc.js" type="text/javascript"></script>
   6:     <script src="http://ajax.microsoft.com/ajax/jquery/jquery-1.3.2.min.js" type="text/javascript"></script>
   7: </content>
   8:  
   9:  
  10:  
  11:  
  12: #using (Html.BeginForm())
  13: #        {
  14:           
  15:  <div>
  16:             <fieldset>
  17:                 <legend>Event Information</legend>
  18:                 <p>
  19:                     <label for="eventname">Event name:</label>
  20:                     ${Html.DropDownList("eventname", EventList)}
  21:                 </p>
  22:                 <p>
  23:                     <label for="eventdate">Event Date:</label>
  24:                     <select id="eventdate">
  25:                         <option value="">Select Date:</option>
  26:                     </select>
  27:                 </p>
  28:                 <p>
  29:                     <input type="submit" value="See Event Info" />
  30:                 </p>
  31:             </fieldset>
  32:         </div>         
  33:           
  34:           
  35: #}

 

If you are wondering why my second selection list is not generated by the HtmlHelper class it is only because I was not able to append to it using jQuery.  Since it really wasn’t needed anyway I just decided not to bother.

The name of my view is called Events and it resides in my Home controller and the code for populates that view looks like this.

   1: public ActionResult Events()
   2:         {
   3:             IList<EventDto> events = new List<EventDto>();
   4:             const int upper = 5;
   5:             for (int i = 0; i < upper; i++)
   6:             {
   7:                 var eventItem = new EventDto() {EventCode = i.ToString(), Eventname = string.Format("Name {0}", i)};
   8:                 events.Add(eventItem);
   9:             }
  10:  
  11:             var eventList = new SelectList(events, "EventCode", "EventName");
  12:             ViewData["EventList"] = eventList;
  13:             return View();
  14:         }

Nothing special here.  I am just creating a list of events and then passing it to a SelectList so it can be populated in the view.

So when the page loads the HTML looks like this:

   1:  
   2:                 <legend>Event Information</legend>
   3:                 <p>
   4:                     <label for="eventname">Event name:</label>
   5:                     <select id="eventname" name="eventname"><option value="0">Name 0</option>
   6: <option value="1">Name 1</option>
   7: <option value="2">Name 2</option>
   8: <option value="3">Name 3</option>
   9: <option value="4">Name 4</option>
  10: </select>
  11:                 </p>
  12:                 <p>
  13:                     <label for="eventdate">Event Date:</label>
  14:                     <select id="eventdate">
  15:                         <option>Select Date:</option>
  16:                     </select>
  17:                 </p>
  18:                 <p>
  19:                     <input value="See Event Info" type="submit">
  20:                 </p>
  21:             

And the page looks like this:

page1

The JsonResult Function

ASP.Net MVC comes with different controller actions, one of them being the JsonResult action.  Like the ActionResult, the JsonResult sends data back to the view but in this case, the response is converted into JSON.

   1: [AcceptVerbs(HttpVerbs.Get)]
   2:         public JsonResult EventDates(string eventCode)
   3:         {
   4:             IList<EventDateDto> eventDates = BuildEventDates(eventCode);
   5:             return Json(eventDates);
   6:         }

In writing the function, first I have to tell it action to respond do.  In this case I want it to respond to “GET” requests, so I need to add the AcceptVerbs attribute to the function with the “GET” verb stated.  The function needs to have the parameter for the event code that the user selected in the dropdown, and then based on the parameter the application gets a list of dates.  These collection dates (are formatted as strings in this case) are then passed back by calling the Json() function.

 

The jQuery function:

So in order to get the data for the second dropdown we need to make an AJAX call to the server and pass it the value of the first dropdown when its “change” event is fired.

When the event is fired, we can then use the jQuery $.AJAX call to make a “GET” request to the URL as such:  …/Home/EventDates?eventCode=3.  When you look at the header of the request you also notice that “Accept” attribute is set to “application/json, text/javascript, */*”.

   1: <script type="text/javascript" charset="utf-8">
   2:         $(function(){
   3:           $("select#eventname").change(function(){
   4:                 var data = $(this).val();
   5:                 var json = {eventCode: data};
   6:                 
   7:                 
   8:                 $.ajax({
   9:                   type: "GET",
  10:                   url: "/Home/EventDates",
  11:                   data: json,
  12:                   dataType: "json",
  13:                   error: function(xhr, status, error) {
  14:                     alert("error routine");
  15:                   },
  16:                   success: function(res){
  17:                     var $dropdown = $("select#eventdate");
  18:                     $dropdown.find('option').remove().end();
  19:                     $dropdown.append('<option value="">Select Date</option>');
  20:                     for (var i = 0; i < res.length; i++) {
  21:                         $("select#eventdate").append('<option value="' + res[i].EventDateName + '">' + res[i].EventDateName + '</option>');
  22:                       }
  23:                       
  24:                   }
  25:                 });
  26:           });
  27:         })
  28:         </script>

Notice that the data we are passing must in the request must be in a jSon format.  So in the case the data we are passing is {eventCode:3}.  The response we get back is:

[{"EventDateCode":"10/27/2009","EventDateName":"10/27/2009"},{"EventDateCode":"10/30/2009","EventDateName":"10/30/2009"},
{"EventDateCode":"11/2/2009","EventDateName":"11/2/2009"},{"EventDateCode":"11/5/2009","EventDateName":"11/5/2009"},
{"EventDateCode":"11/8/2009","EventDateName":"11/8/2009"},{"EventDateCode":"11/11/2009","EventDateName":"11/11/2009"},
{"EventDateCode":"11/14/2009","EventDateName":"11/14/2009"},{"EventDateCode":"11/17/2009","EventDateName":"11/17/2009"},
{"EventDateCode":"11/20/2009","EventDateName":"11/20/2009"}]

 

If the response is successful, the callback function takes the collection that is returned and build a string of <option> tags and append it to the select object.

page1after



Creating a Custom Trace Listener for WCF

clock June 15, 2009 11:00 by author Steve

Introduction

We have been using WCF to consume a lot of 3rd party web services, and one of things we depend on when testing is being able to see the actual request and response that is being sent to and from the host.  This is expecially inportant in 3rd party services, because the service is essentially a black box in which there is no way to know what is going on except that you send it a request and you get a response back.  I posted how, out of the box, you can configure WCF to write the message to a trace xml file, but one of things about writing to a file is that if you or your testers do not have access to the web server where the file is being written then this is not going to work.

Solution

The way around this problem is to create a custom trace listener that catches the messages and does what ever you want.  Here is a simple sample.

Create a class that inherits from the TraceListiner class.

    1 using System.Diagnostics;

    2 

    3 namespace WcfTrace.Trace

    4 {

    5     public class WebTraceListener : TraceListener

    6     {

    7         public override void Write(string message)

    8         {

    9             //write you custom code here

   10             Debug.WriteLine(message);

   11         }

   12 

   13 

   14         public override void WriteLine(string message)

   15         {

   16             //write your custom code here

   17             Debug.WriteLine(message);

   18         }

   19     }

   20 }

The next thing to do is to wire up the custom class in the web.config (or app.config) so that when messages are created ,they caught by the custom trace listener class.  The config below is telling source messages to use the sharedListener named xml which the custom trace listener listed above.

  108   <system.diagnostics>

  109     <sources>

  110       <source name="System.ServiceModel" switchValue="Information, ActivityTracing" propagateActivity="true">

  111         <listeners>

  112           <add name="xml" />

  113         </listeners>

  114       </source>

  115       <source name="System.ServiceModel.MessageLogging">

  116         <listeners>

  117           <add name="xml" />

  118         </listeners>

  119       </source>

  120     </sources>

  121     <sharedListeners>

  122       <add name="xml" type="WcfTrace.Trace.WebTraceListener,WcfTrace.Trace" />

  123     </sharedListeners>

  124   </system.diagnostics>

  125 

  126   <system.serviceModel>

  127     <diagnostics>

  128       <messageLogging

  129           logEntireMessage="true"

  130           logMalformedMessages="false"

  131           logMessagesAtServiceLevel="true"

  132           logMessagesAtTransportLevel="false"

  133           maxMessagesToLog="300000"

  134           maxSizeOfMessageToLog="200000"/>

  135     </diagnostics>

That's it.  Now when ever a web service call is made, the custom trace listener class is executed, passing it the trace messages.



Entity Framework 4.0 Sneak Peak - POCO Goodness!

clock May 12, 2009 04:09 by author Steve

A while back I posted that I was looking into the viability of using Entity Framework, and at the time I was genuinly excited about what it had to offer. I even stated that I would report back to you my findings.  So I set out to try and create a domain layer that used EF as an O/R Mapper but also tried maintained percistance ignorance with the data objects it was passing around.  Percistance Ignorance being the objects containing the data retrieved from the database should not contain any information about the mechanism it used to retrieve the data.

To be honest, I was pretty disappointed with my findings. Entity Framework 3.5 is pretty intrusive.  All data objects had to either impliment an EntityFramework interface or had to be a subclass of an EntityObject class.

I never went back and revisited that blog post, mainly because I did not want to spew vile about the product; so I just let it be and started looking into nHibernate.  I was sort of down because all the good tools like LightSpeed cost money.

Well now it looks like Microsoft has heard our gripes about the products short comings and is going to do something about it.

You can read all about it here.

 



MVC and Thumbnails with StructureMap

clock May 2, 2009 13:47 by author Steve

In the process of looking for a way to read large images from a file or database, and displaying them as thumbnails, while all the while doing this using the MVC framework and TDD; I came accross two really good blog samples.  One by Josh Holmes and the other approach by Tom Janssens.  I took the latter example, and it worked like a charm.

The only I change I made was to refactor the singleton function that retrieves the MemoryStream so that I can test it.  I used StructureMap in this case so I could inject it into the ThumbNail class.  Therefore the GetMemoryStream function which was static so it could used as a singleton was moved to it's own class.

Here is the interface:

    7     public interface IImageMemoryManager

    8     {

    9         MemoryStream GetStream(Image image, int width, int height, ImageFormat imageFormat);

   10     }

The function in the sample that converts the image into a MemoryStream will then located in the concreate class ImageMemoryManager which impliments the above function.

On the Application_Start event of my application, I can call out to a bootstrapper class that loads up StructureMap mappings and saves it so it can be used later.

   28         protected void Application_Start()

   29         {

   30             RegisterRoutes(RouteTable.Routes);

   31             BootStrapper.ConfigureStructureMap();

   32             ControllerBuilder.Current.SetControllerFactory(new GalleryControllerFactory());

   33         }

The Bootstrapper class configures the StructureMap mappings.

    6     public class BootStrapper

    7     {

    8         public static void ConfigureStructureMap()

    9         {

   10             StructureMapConfiguration.AddRegistry(new StructureMapSiteRegistry());

   11         }

   12     }

 And here is mappings: 

    9     internal class StructureMapSiteRegistry : Registry

   10     {

   11         protected override void configure()

   12         {

   13             ForRequestedType<IContentType>().TheDefaultIsConcreteType<ContentType>();

   14             ForRequestedType<IPictureRespository>().TheDefaultIsConcreteType<SqlPictureRespository>();

   15             ForRequestedType<IImageMemoryManager>().TheDefaultIsConcreteType<ImageMemoryManager>().CacheBy(

   16                 InstanceScope.Singleton);

   17         }

   18     }

Notice the IImageMemoryManager maps to the contrete class ImageMemoryManager, and since initially it was a singleton class; I want to designate the mapping's InstanceScope as Singleton by using the CacheBy function.

 I can then inject the these mappings into all my controller by inheriting from the DefaultControllerFactory class calling the GetInstance function in StructureMap to build out the injections. 

    7     public class GalleryControllerFactory : DefaultControllerFactory

    8     {

    9         protected override IController GetControllerInstance(System.Type controllerType)

   10         {

   11             IController result = null;

   12             if (controllerType != null)

   13             {

   14                 try

   15                 {

   16                     result = ObjectFactory.GetInstance(controllerType) as Controller;

   17                 }

   18                 catch(StructureMapException ex)

   19                 {

   20                     Debug.WriteLine(ObjectFactory.WhatDoIHave());

   21                 }

   22             }

   23             return result;

   24         }

   25 

   26     }

By the way, you can get a real good sample code to this by taking a look at the MvcContrib samples. 

Now I that the function is isolated I can test it.

   72         [TestMethod()]

   73         public void GetStreamTest()

   74         {

   75             ImageMemoryManager target = new ImageMemoryManager(); // TODO: Initialize to an appropriate value

   76             Image image = Image.FromFile(@"C:\Projects\Gallery\source\Gallery.Tests\Images\shuttle5-768.jpg");

   77             int width = 100;

   78             int height = 100;

   79             ImageFormat imageFormat = ImageFormat.Bmp;

   80 

   81             MemoryStream actual = target.GetStream(image, width, height, imageFormat);

   82             Assert.IsNotNull(actual);

   83         }

I could probably put together a more rigorous test here, but its testable.

The ThumbNailResults class which is returned to the view now looks like this.

   10     public class ThumbnailResult : FileStreamResult

   11     {

   12 

   13 

   14         public ThumbnailResult(Image input) : this(input, input.Width, input.Height)

   15         {

   16         }

   17 

   18         public ThumbnailResult(Image input, int width, int height) :

   19             base(

   20             ((IImageMemoryManager) StructureMap.ObjectFactory.GetInstance(typeof (IImageMemoryManager))).GetStream(

   21                 input, width, height, ImageFormat.Png),

   22             "image/png")

   23         {

   24         }

   25 

   26 

   27 

   28 

   29     }

Thanks to Tom and Josh in providing really nice examples.  It's nice to see the community contributing with really good examples to such a new framework!

 

 

 

 

 

 

 

 



ASP.Net MVC 1.0 and Resharper 4.5 Beta released

clock March 18, 2009 05:05 by author Steve

Wow! It's an exciting week to be a dot net developer. 

The long awaited official version of ASP.NET MVC was released during MIX 09.  As far as getting up to speed, there is a butt-load of stuff on the ASP.Net website.

 Also, those of us who cannot write a line code without Resharper will be happy to know the 4.5 beta is out which segnificantly improves its performance.  That being one of my big gripes about the product, especially when you try and run it in a virtual environement with big solutions, am really excited to take this new edition out for a drive.  You can see the details about it here.



Calendar

<<  March 2010  >>
MoTuWeThFrSaSu
22232425262728
1234567
891011121314
15161718192021
22232425262728
2930311234

View posts in large calendar

Sign in