dot net miscellany

  • ASP.NET MVC + RSS ActionResult

    ASP.NET’s new MVC framework (currently at RC2 release) makes syndicating your data ridiculously simple to implement.

    A Trivial Example

    For example, in a trivial blogging MVC site your ‘Home’ Controller may have a ‘Posts’ Action handler, so when you navigate to ‘http://server/home/posts’ the ‘Posts’ action handler will retrieve all blog posts (or the 5 most recent) and set them as the View’s Model data.

    Also, if your ‘Posts’ Action handler accepts an int32 parameter you could view a specific blog entry by navigating to ‘http://server/home/posts/123’. In this case, the  ‘Posts’ action handler will retrieve only post number ‘123’ and will set that post as the View’s Model data.

    ASP.NET MVC allows you to return the Model data retrieved by the Controller in a variety of ‘out-of-the-box’ formats, including the ASPX, JSON, Plain Text etc.

    There isn’t currently an RSS/Atom ActionResult (which is what every Action Handler in a Controller must return), but its really easy to ‘roll your own’. See the steps below.

     

    Implementation

    1) Build your own RssResult : ActionResult

    Firstly, you need to create a new class and derive from the abstract class ActionResult. I’ve called mine ‘RssResult’. Create it wherever you see fit, but I just put mine in the Controllers namespace.

    The only method you need to override in your new derived class is the ‘ExecuteResult’ method. This method effectively creates the output (be it; HTML, JSON, Plain Text etc) which is to be returned to the client.

    So in our overriden ‘ExecuteResult’ method, we first set the response’s content type to ‘application/rss+xml’, then pass our syndication feed to the Rss20FeedFormatter which is part of WCF’s System.ServiceModel.Syndication namespace.

    This formats all our syndication feed data into RSS compliant XML which is then written to the response stream, which eventually will be returned to the calling client.

    namespace RssMvc.Controllers
    {
        using System;
        using System.Collections.Generic;
        using System.Linq;
        using System.Web;
        using System.Web.Mvc;
        using System.ServiceModel.Syndication;
        using System.Xml;
    
        public class RssResult : ActionResult
        {
            public SyndicationFeed Feed { get; set; }
    
            public RssResult() { }
    
            public RssResult(SyndicationFeed feed)
            {
                this.Feed = feed;
            }
    
            public override void ExecuteResult(ControllerContext context)
            {
                context.HttpContext.Response.ContentType = "application/rss+xml";
    
                Rss20FeedFormatter formatter = new Rss20FeedFormatter(this.Feed);
    
                using (XmlWriter writer = XmlWriter.Create(context.HttpContext.Response.Output))
                {
                    formatter.WriteTo(writer);
                }
            }
        }
    }

     

    2) Add a new Action Handler in your Controller

    Next, create a new Controller Action inside your ‘Home’ controller (or whatever controller you want).

    Inside the Action we will create the syndication feed and syndication items therein. (in my example, I’m creating a few dummy feed items, but in the real-world you would make a call to the Model to return this data).

    Once you have created your Syndication feed and feed items (once again using the System.ServiceModel.Syndication namespace), return an instance of your new RssResult, passing your feed.

    public ActionResult Rss()
    {
        List<SyndicationItem> items = new SyndicationItem[] 
        {
            new SyndicationItem("Blog 1", "Joe's 1st Blog", null),
            new SyndicationItem("Blog 1", "Joe's 1st Blog", null),
            new SyndicationItem("Blog 1", "Joe's 1st Blog", null)
        }.ToList();
    
        SyndicationFeed feed = new SyndicationFeed("Joe's Blog Posts", "http://blogs.msdn.com/jowardel RSS Feed",Request.Url, items);
                    
    
        return new RssResult(feed);
    }
    
     
    3) Done! – People can subscribe to your Blogs by RSS

    So now when you navigate to ‘server/home/rss’ your ‘Rss’ action is invoked inside the ‘Home’ controller, which creates the feed and passes it to the RssResult which formats it and writes it to the HttpContext’s Response stream to be rendered in your browser of choice!

    Comment or contact me direct if you have any questions, suggestions etc – I’d be interested in hearing from you. Hope this helps.

    image

     

    Code available here:

  • ASP.NET MVC + Silverlight

    I’ve recently been playing around with ASP.NET’s new MVC (Model View Controller) framework and have to say, its pretty cool. You can find MVC downloads, tutorials and other errata here.

    However, I ran into abit of a problem with MVC when using Silverlight applications inside MVC Views. Views should simply display the Model data passed to it by the Controller using (as illustrated in diagram 1).

    <asp:Content ID="indexContent" ContentPlaceHolderID="MainContent" runat="server">
        <h2><%= Html.Encode(ViewData["Message"]) %></h2>
        <p>
            To learn more about ASP.NET MVC visit <a href="http://asp.net/mvc" title="ASP.NET MVC Website">http://asp.net/mvc</a>.
        </p>
    </asp:Content>

     

    If you want your View to contain a Silverlight app that contains no Model data, then there’s no problem. Simply embed the Silverlight into the ASPX View using either the raw HTML or the ASP.NET Silverlight control and it works.

    However, the problem comes when you want the Silverlight app to display/manipulate/use the Model data passed to the View by the Controller. You can of course get the Model data into Silverlight using web service calls or by making HTTP requests from Silverlight to your Controller (as illustrated by Tim Heuer in this post), but this violates the MVC pattern. Ideally your Silverlight app should work in a similar way to the MVC Views, simply displaying the data that is passed to it.

     

    So, how do you initialise Silverlight with the data it needs? Well, I found that I could pass all the data my Silverlight app needed to display using the ‘initParams’! – sneaky huh.

    Basically, these are the steps involved:

    Controller
    • Create your custom Action inside your Controller (in this example, the controller is ‘Home’ and the Action is ‘Search')
    • The Controller invokes the Search function in the appropriate Model
    • The Model returns the search results to the Controller
    • The Controller returns the ActionResult containing the Search Results as the View’s Model data
    public ActionResult Search()
    {
        // Call Model to do Search
    
        // Set results as View's Model data (we're using dummy data)
        ViewData.Model = new SearchResult[] 
        {
            new SearchResult(){Title="Search Result 1", Relevance=100}, 
            new SearchResult(){Title="Search Result 2", Relevance=75}, 
            new SearchResult(){Title="Search Result 3", Relevance=100} 
        }.ToList();
    
        // Return View ActionResult containing our Model Data
        return View();
    }
     
    View
    • Next, create your View ASPX page. I’ve made my View strongly typed, so I can reference the collection of type SearchResult (Model data) directly instead of having to cast it
    • On your View page, embed the standard Silverlight HTML markup
    • Inside the containing div I have some inline C# which copies the Model data into a new collection of anonymous type (you could just use the SearchResult collection passed in, but if I was only interested in a subset of the properties in SearchResult, or wanted to add my own or change their names etc, then creating a collection of a new anonymous type is very handy. Just make sure the type you will deserialize the JSON to inside your Silverlight app contains the exact same properties as your new anonymous type!)
    • The new collection is then serialized to JSON using the System.Web.Script.Serialization.JavaScriptSerializer and stored in a StringBuilder
    • The JSON is then URL encoded and concatenated into a string which matches Silverlight’s InitParams definition (e.g. key=value)
    • Finally, some more inline code to output the necessary ‘initParams’ param markup, passing our custom initParams string as the value
    <%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<List<MvcSilverlight.SearchResult>>" %>
    
    <asp:Content ID="Content1" ContentPlaceHolderID="head" runat="server">
        <title>Silverlight</title>
    </asp:Content>
    <asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
        <h2>Silverlight Results Page</h2>
        
        
        <div id="silverlightControlHost">
        
            <%             
                System.Text.StringBuilder jsonText = new System.Text.StringBuilder();
    
                var results = ViewData.Model.Select(sr => new {Title=sr.Title, Relevance = sr.Relevance });            
                    
                System.Web.Script.Serialization.JavaScriptSerializer serializer = new System.Web.Script.Serialization.JavaScriptSerializer();
    
                serializer.Serialize(results, jsonText);
    
                string initParams = string.Format("{0}={1}","model", HttpUtility.UrlEncode(jsonText.ToString()));
    
            %>
            
            <object data="data:application/x-silverlight-2" type="application/x-silverlight-2" width="300px" height="300px">
                <param name="source" value="/ClientBin/SilverlightApplication1.xap" />
                <param name="minRuntimeVersion" value="2.0.31005.0" />
                <% Response.Write(string.Format("<param name=\"initParams\" value=\"{0}\"/>", initParams)); %>
                <param name="windowless" value="true" />
                <param name="Background" value="#00FFFFFF" />
            </object>
        </div>
    </asp:Content>
     
    Silverlight
    • Modify your App.xaml.cs file in your Silverlight project
    • In the Application_Startup event handler store the InitParams to a static IDictionary<string,string> for reference later
    public static IDictionary<string, string> initParams = new Dictionary<string, string>();
    
    private void Application_Startup(object sender, StartupEventArgs e)
    {
        this.RootVisual = new Page();
    
        App.initParams = e.InitParams;
    }

     

    • In your Silverlight application’s Page_Loaded event handler in Page.xaml.cs (or wherever you want really), retrieve the Model data from the IDictionary, using the key (“model”)
    • Once you have your Model data as a string, Url decode it, then deserialize using the DataContractJsonSerializer.
    • If you are passing complex types to Silverlight as we are in this example, you must have a class defined in your Silverlight app to cast the Model data to. This class must be attributed with the DataContract attribute, and each of its publicly accessible properties must attributed with the DataMember attribute
    • Finally, cast the deserialized object to your replica type / collection of replica type, and you’re done!
    void Page_Loaded(object sender, RoutedEventArgs e)
    {
        // Deserialize Init Params
        List<SearchResult> results = null;
    
        using (MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(HttpUtility.UrlDecode(App.initParams["model"].ToString()))))
        {
            DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(List<SearchResult>));
    
            results = (List<SearchResult>)serializer.ReadObject(ms);
        }
    
        // Set deserialized search results as DataGrid ItemsSource
        this.ResultsGrid.ItemsSource = results.ToList();            
    }
    

     

     

    • Tada! The SearchResult collection is passed from the Model through the Controller, to the View and finally into Silverlight. Without breaking any MVC rules!

    2

     

    Hope that helps. You can get the source code for this sample here.

  • Extending Object!

    Ever wanted to add your own methods to Object...or any other type for that matter?

    I've recently started playing around with Extension methods in C# and they're pretty damn cool.

    To add your own method to a Type:

    1. First create a static class, and inside it make a static method with your chosen method signature. The important thing to note is that the method takes as an argument 'this object obj'. This tells the compiler that this method should be callable from type 'object'. The 'this' keyword is a little confusing but it is really to differntiate the argument from a regular static method which accepts an object arg

      My method 'SayHello' simply returns the string "Hello Joe" - a trivial and narcissistic example :)






    2. Now if you create any instance of the object type in your code (the namespace that hosts your extension method must be imported) the SayHello() extension method is available!

      It is also included in every derived type - which in .NET is every single type! (e.g. Int32)

     



    This is about as trivial an example as you are likely to find on extension methods but they can be extremely useful - for example, the whole LINQ infastructure is made with extension methods.

     Enjoy

     

  • How to host Silverlight in SharePoint

    Hosting Silverlight in SharePoint is actually pretty simple in its basic form. If you want more control over your Silverlight app within SharePoint there's always the excellent Silverlight Blueprints. The only prerequisite i'm aware of is that the IIS server SharePoint is running on has a mime type that support Silverlight (extension: .XAP, MIME-type: application/x-silverlight).

    The simple way I've been doing it, is as follows:

    1. Upload the Silverlight XAP to your SharePoint site's 'Shared Documents' document library.



    2. Create a new Web Part page in SharePoint (ensure the Document Library is set to 'Shared Documents')




    3. Then Edit the page and add a Content Editor WebPart




    4. Open the Source Editor and paste the HTML source from your Silverlight test page




    5. Adjust the Width and Height so you can see the page and your Silverlight app


     

    And you're done! - Your Silverlight app is hosted in SharePoint. My next blog post will show how you can use SharePoint's web services to perform actions on WSS from within your Silverlight App. Quite an appealing prospect given that the world and his dog are now using SharePoint but still with the standard vanilla UI. Imagine the possibilities of sexing up WSS' collaboration features with Silverlight.

     

  • Using the Model-View-Presenter (MVP) Design Pattern to enable Presentational Interoperability and Increased Testability

    What is MVP?

    Model View Presenter (MVP) is a software design pattern which essentially isolates the user interface from the business logic. MVP is derived from the Model View Controller (MVC) pattern, and originally conceived by the renowned Agile software architect, Martin Fowler.

    The principal behind the MVP pattern is that an implementing application should be split into three core components; Model, View and Presenter:

    §  The Model component encapsulates all Business Logic and Data in the application. This may be a database transaction or a call to a web service, etc.

    §  The View component represents the application’s Presentation layer (User Interface); this may be a standard Win Forms client, an ASP.NET Web part or Mobile client. In the MVP pattern, the View should be simplistic and responsible for rendering and accepting user input only.

    §  The Presenter component is responsible for orchestrating all the application’s use cases. For example a sample operation would involve; taking user input from the View, invoking operations on the Model and if needed, setting data in the View to indicate the operation’s result.

    View

    Presenter

    Model

     - Presenter

     - IView
     
    - Model

     

     

     

     

     

    The advantages of implementing the MVP pattern in a project with a presentation tier are:

    §  Isolation of User Interface from Business tier

    §  Easily interchangeable Views (user interfaces)

    §  Ability to test all code in the solution (excluding visual presentation and interaction)

     

     

    Example

    Throughout this document, the explanation of the MVP design pattern, code extracts and testing strategies will all refer to an example Search application. This search application is extremely basic and used for purely illustrative purposes only.

    It consists of a single Use Case scenario; Search, which executes as follows:

    1.       User enters a search criteria (e.g. “test”)

    2.       The User initiates a search in the UI (e.g. Button click)

    3.       The View component handles the search event, and invokes the ‘Search()’ function on the Presenter

    4.       The Presenter extracts the search criteria string from the View’s ‘SearchCriteria’ property

    5.       The Presenter invokes the Business operation ‘Business Search’ on the Model, passing the search criteria as an argument

    6.       The Model returns all matching results for the given search criteria

    7.       The Presenter sets these results in the View component’s ‘Results’ property 

     

     

     

    Detailed Explanation

    Model

    The MVP pattern is chiefly concerned with isolating the user interface from the business logic and as such the Model component’s design is not specified in any detail.

    Since the Presentation component is responsible for orchestrating business use cases, the Presentation component contains a reference to both the View and Model components.

    However it is generally accepted as good practice to decouple the Model from the Presentation component. To do this, it is recommended to create an interface for the Model which defines all the business logic operations contained in the Model. Then use the ‘Factory method’ pattern (a creational pattern) to return a concrete implementation of the Model for use in the Presentation component. This allows the Model to be interchanged without any modification to the Presentation component.

     


     

    View

    The View component represents the Presentation layer and can be implemented in a variety of UI technologies (Windows Forms, Web-Page, Web-Part, Silverlight etc) on a range of platforms (Client, Web, Mobile).

    The View’s responsibilities are limited to rendering itself, accepting user input and handling user events on controls (e.g. Button clicks).

    The View does not perform any business logic, or directly interact with the Model. Instead it invokes methods on the Presenter. The Presenter in-turn calls business operations on the Model and then [in some cases] sets properties on the View to indicate the operation’s result.

    Because the View is designed to be fully interchangeable, the View component implements an interface which defines the methods and properties all concrete Views must implement.

     

     


    The above diagram illustrates the architecture of the View component. To better understand how the View and Presenter components interact, these components’ will be discussed in the context of the example Search Web-Part application.

    In the preceding diagram, the View component’s interface ‘IView’ defines a property ‘SearchCriteria’ of type string with read permissions and a property ‘Results’ of type string collection with write permissions.

    For the purposes of the example Search application, it is necessary for any View to have an input which accepts the user’s search criteria (e.g. TextBox), and an output which displays the matching results (e.g. ListBox).

        public interface IView

        {

            string SearchCriteria { get; }

     

            List<string> Results { set; }

        }

     

     The Presenter component is never given a direct reference to the View component’s concrete implementation. Instead it references the View component through the View Interface ‘IView’. This allows the View implementation to be changed (e.g. from a Web Part control to a Windows Form client) without the Presenter being modified. Therefore when the View’s interface is developed, thought should be given as to how the Presenter will interact with the View’s data. For example, in the example Search application, the Presenter will need to retrieve (‘get’) the user’s search criteria string and once the search has been performed (by the Model) the resultant output must be displayed to the user (‘set’).

    It is also important to develop View interfaces using only Framework types or Business types (as defined in the Model), not presentation technology-specific types. E.g. it would be possible to define the ‘Results’ property to be of type System.Web.UI.WebControls.BulletedList, however this is specific to an ASP.NET Views and would be inefficient to implement on a Windows Form client View implementation.

     

        public class ViewImpl : WebPart, IView

        {

     

            private Presenter presenter;

     

            Label lblSearch = new Label() { Text = "Enter bank to search for: " };

            Button btnSearch = new Button() { Text = "Search" };

            BulletedList resultsList = new BulletedList();

            TextBox tbSearchCriteria = new TextBox();

     

            public ViewImpl()

            {

                this.presenter = new Presenter(this);

            }

     

            protected override void CreateChildControls()

            {

                this.Controls.Clear();

                this.btnSearch.Click += new EventHandler(btnSearch_Click);

                this.Controls.Add(this.lblSearch);

                this.Controls.Add(this.tbSearchCriteria);

                this.Controls.Add(this.btnSearch);

                this.Controls.Add(this.resultsList);

                this.ChildControlsCreated = true;

            }

     

            void btnSearch_Click(object sender, EventArgs e)

            {

                this.presenter.Search();

            }

     

            #region IView Members

     

            public string SearchCriteria

            {

                get { return this.tbSearchCriteria.Text; }

            }

     

            public List<string> Results

            {

                set

                {

                    this.resultsList.Items.Clear();

     

                    List<string> results = new List<string>(value);

     

                    foreach (string r in results)

                    {

                        this.resultsList.Items.Add(r);

                    }

                }

            }

     

            #endregion

        }

     

    The above code extract contains all the code required to implement a very basic search ASP.NET Web Part that also implements the IView interface.

    The following list dissects the structure and members of the example Search Web Part View implementation:

    §  Firstly, the variables are declared, including a reference to the Presenter, also a number of UI controls.

    §  ViewImpl’s constructor, instantiates the Presenter, passing a reference to itself to the Presenter’s constructor. The Presenter’s constructor signature defines a parameter of type IView, and since ViewImpl implements IView, the self-reference can safely be passed. This allows the Presenter to invoke methods/properties on the IView instance and visa-versa allowing the View to invoke methods/properties on the Presenter instance.

    §  ViewImpl overrides the Web Part method ‘CreateChildControls()’ so as to perform custom rendering of itself and its children. The ‘Search’ Button control also registers a new Event Handler to handle button clicks.

    §  The Button click event handler, does not perform any logic or call any Business Operations, instead it simply invokes a ‘Search()’ method on the Presenter (note that the method does not take any parameters).

    §  Next, the IView implementations. The ‘SearchCriteria’ property returns the Text property of the TextBox input control which contains the user’s search criteria. The Results property populates the List control with the data passed into it.

     


     

    Separation of Concerns

    Although the MVP pattern prescribes the implementation of only a very basic View with little or no logic, it is often desirable or necessary to include validation, error handling, initialization, localization and general house-keeping code. These operations are specific to be presentation-technology being employed and as such are not something that can be handled by the Presenter; however they are also not strictly related to the rendering of the View.

    Therefore in the development of this simple Search example MVP application, it was decided to experiment with a separation of View concerns, whereby the View would be split into a Logic tier and a Presentational tier.

     

     It is important to note that implementing the View as two separate classes can lead to more complex code and requires greater design consideration, as it may be prudent to declare certain IView members as abstract in the Logic tier as they require no presentational logic and should therefore be implemented in the Presentational tier only. This is just one example of a design consideration that must be taken when employing this pattern.

    Therefore, this pattern is only really suited to complex Views where implementation-specific logic is essential.

     


       


    Logic Tier

    In the context of the Search web part example, the logic tier of the View component is responsible for:

    §  Implementation of the IView interface – The body of these properties includes validation, error handling logic etc.

    §  Inheriting from WebPart

    §  Initialisation – Instantiating the Presenter, setting up resources specific to the implemented technology (e.g. Retrieving parameters from the HTTP request object)

    §  Validation – E.g. Ensuring the results assigned to the Results string collection are valid

    §  Error handling – E.g. Handling / throwing exceptions generated during the aforementioned operations

    It is worth noting that although the Logic tier inherits from System.Web.UI.WebControls.WebParts.WebPart, it is marked as an abstract class to prevent instantiation. This is because it is only responsible for implementation-specific logic, not rendering of itself and child controls.

    Presentational Tier

    The Presentation tier then inherits from the Logic tier, and is solely responsible for all User Interface and Interaction matters. In the context of this Search example, these responsibilities are:

    §  UI Initialisation – E.g. Webpart title, Size, Positioning etc

    §  Creation of all constituent controls (Buttons, TextBoxes, Labels, Lists etc)

    §  Rendering of these controls – E.g. CreateChildControls()

    §  Event Handlers registered to constituent Controls

    §  Overridden IView member implementations – The overridden IView members call the Logic tier’s IView members to perform validation etc, and then render the results to the respective UI controls.

     


     

    Presenter

    As illustrated in the View implementation C# code extract, the View (like many applications) is the entry-point for the application, and is responsible for creating the Presenter which in-turn creates the Model. The only difference between this example MVP search web part and a non-MVP web part is that the MVP View contains no business logic, apart from one call to invoke the Search operation on the Presenter instance. Apart from this, it is solely dedicated to the rendering of its constituent UI Controls and the getting and setting of the data therein.

        public class Presenter

        {

            private readonly IView view;

     

            public Presenter(IView viewImpl)

            {

                this.view = viewImpl;

            }

     

            public void Search()

            {

                this.view.Results = Model.Search(this.view.SearchCriteria);

            }

     

        }

     

     The Presenter in the example Search application (see above code extract) is very simple and contains a reference to a View (through the IView contract), a constructor which takes an IView reference as its single parameter and a single method ‘Search()’.

    The ‘Search()’ method in this example, illustrates how the Presenter interacts with the View. As shown in the code extract, the method does not take any arguments (such as the user’s ‘search criteria’). Instead it directly obtains the search criteria string from the View implementation because the Presenter knows that any View implementation must contain the read-only property ‘SearchCriteria’ of type string. Similarly, instead of returning the results of the Search through a return type (the ‘Search()’ method signature defines a return type of void), it directly sets the results to the write-only property ‘Results’ of type string collection.

    Notice also, that the ‘Search()’ method does not perform the Search operation itself, instead it invokes the Model to perform this task since its primary responsibility is to execute business operations.

    This example Presenter clearly illustrates the Presenter’s relationship with both the View and the Model. It does not know what View it is retrieving and setting data to, it is only aware of the IView interface which acts as a contract between the two components. Similarly, the Presenter does not need to know which Model it is invoking on behalf of the View. If the Presenter’s interaction with the Model is also performed using an interface (e.g. IModel) then it becomes decoupled from both of its sibling components.

    Unfortunately, the Presenter illustrated above in the example Search application does not perform much intermediary business logic such as validation, event handling, logging and other middle-tier actions. However, it should be clear that these middle-tier actions are ideally suited to the Presenter and can be implemented and tested relatively easily.

     


    Testing MVP Applications

    The Problem

    In traditional applications, the user interface presentational tier is tightly coupled to the business logic tier. This is because Win and Web applications contain ‘code-behind’ which performs operations both during the User Interface’s lifecycle (e.g. Page Load) and when the user interacts with the UI (event handler attached to a control’s event e.g. button click).

    This code-behind becomes (particularly in large or complex applications) responsible for both rendering and business logic invocation. Therefore the code-behind is tightly coupled to both the Presentation tier and the Business tier. Furthermore, it is frequently necessary for the code-behind to invoke business operations and then transform the results, handle exceptions and perform complex flow-control based on the result of an operation etc. The resultant design can become unstructured and difficult to maintain.

    A further, often neglected effect of bloated code-behind is an un-testable presentation tier. Although the appearance and interaction of a User Interface can only really be tested by either manual or scripted automation tests, the overuse of code-behind means there is a great deal of logic that happens in the event handlers in the code-behind, before execution ever passes to the well unit-tested Business tier.

     

    The MVP Solution

    Implementing the MVP design pattern greatly increases the ability to test the presentation tier, since the View component consists almost entirely of visual logic (UI controls and basic event handlers), and all the logic surrounding the calls to the data tiers (Model) is orchestrated by the Presenter.

    This means that if the tests can invoke Presenter functions and inspect the state of the View, the tests will cover almost all logic code. The only part of the application left un-tested is the visual state of the user interface controls. Determining this is extremely difficult to perform programmatically and as such is normally left to manual or scripted automation tests.

    The best way of testing an MVP solution is to use a ‘Mock Object’ in place of the actual View. The mock View implements the IView interface, and is also customised to allow the tests access to View members which are inaccessible in the actual View.

    This technique of mocking the View was used to test the example Search application, as the following code extract illustrates.

     

        public class ViewMock : IView

        {

            public SearchPresenter Presenter { get; set; }

     

            public ViewMock()

            {

                this.Presenter = new Presenter(this);

            }

     

     

            #region ISearchView Members

     

            public List<string> Results { get; set; }

     

            public string SearchCriteria { get; set; }

     

            #endregion

        }

     

    The above code extract illustrates the Mock View implementation created to test the example Search application. It is worth noting however that although the mock View implements the IView interface as the real web part View does, it has an extra property ‘Presenter’ and both set and get permissions on all implemented IView properties (‘Results’ and ‘SearchCriteria’).

    This extra ‘Presenter’ property allows the Unit Test to obtain the Presenter instance without resorting to reflection (it is necessary to obtain the View’s Presenter instance, since it is the Presenter’s functions which will be tested).

    Furthermore, the get and set assessors on the IView implemented properties allow the Unit Test to inspect the mock View’s property values before and after a Presenter’s method has been invoked (so as to assert method pre and post conditions).

    Without testing the mock View and instead testing the actual View, it would not be possible (without using complex and unreliable reflection) to obtain the Presenter to invoke business operations on, set-up test scenarios and inspect the View’s state during tests.

    One concern when testing a mocked View is that the extra properties and increased access to the View members is that the View being tested no longer resembles the actual View in respect of design and structure. This concern is easily remedied since the unit tests holds references to both the mock View instance directly, and also via an IView reference (see code extract below).

            /// <summary>

            /// Search test. Results expected.

            /// </summary>

            [TestMethod()]

            public void SearchTest_ResultsExpected()

            {

                // Setup test pre-reqs and components

                ViewMock mockView = new ViewMock();

     

                Presenter presenter = mockView.Presenter;

     

                mockView.SearchCriteria = "test";

               

                ISearchView testView = mockView;

     

                Assert.IsTrue(testView.SearchCriteria.Equals(mockView.SearchCriteria));

     

                // Search

                presenter.Search();

     

                // Assert results were found

                // (min # results returned from search is 1 - error detail ietm)

                Assert.IsTrue(mockView.ResultsSet.Count > 0);

     

                // Assert results were valid, given the search criteria

                foreach (SearchResult r in mockView.ResultsSet)

                {

                    Assert.IsNotNull(r);

                    Assert.IsTrue(r.Name.IndexOf(testView.SearchCriteria) >= 0);

                }

            }

     

     

     

    A Further Mocking Example

    The mocking solution illustrated above meets the requirements of most simplistic Views that will be developed using the MVP pattern. However as discussed in the section ‘View – Separation of Concerns’ sometimes it is necessary to implement a small amount of presentation technology-specific logic to perform validation, conversion of user input to Business types and visa versa, error handling etc.

    The mock View illustrated previously does not implement any of this logic and would require extra development time to re-implement the View logic inside the mock View. A workaround for this is to split the View into two tiers; a Logic tier and a Presentation tier and then create the mock View as a subclass of the abstract View Logic tier (see diagram below).

     

     

    This allows the mock view access to the Presenter instance, the ability to expose new properties and modify assessors to allow easy inspection of View state during tests and most importantly the ability to invoke all presentation technology-specific logic held in the View Logic tier through invocation of the mock View’s base class.

    Therefore, when a unit test is run which invokes a method on the Presenter, which sets a property in the mock View, the overridden mock View’s property can invoke its base class’ property which in turn executes any validation etc against the input (see code flow diagram below).

        [TestMethod()]

        public void SearchTest_ResultsExpected()

        {

            // Mock View setup (hidden)...  

     

            presenter.Search();

     

            // Assertions (hidden)...

            }

        }

     

        public class Presenter

        {

     public void Search()

            {

                this.view.Results = Model.Search(this.view.SearchCriteria);

            }

            // Rest of Presenter class hidden...

        }

     

        public class MockViewLogic : ViewLogic

        {

            public override List<string> Results

            {

                set

                {

                    base.Results = value;

                }

            }

     

            // Rest of mock view hidden...

        }

     

     

        public class ViewLogic: WebPart, IView

        {

     public virtual List<string> Results

            {

                set

                {

                     // Validation

                     // Error handling

                     // Localisation

                     // etc...

                }

            }

     

            // Rest of view logic abstract class hidden...

        }

     

     

     

    This form of mocking the MVP View allows for more pervasive and complete testing of the View component.

    Presentational Interoperability

    The following code extracts are given so as to illustrate how to implement a View for the example Search application, given its simple IView interface. One View is implemented as an ASP.NET web part, the other as a client side WPF application.

    ASP.NET Web Part Implementation

     

     

       

        public class ViewImpl : WebPart, IView

        {

            private Presenter presenter;

     

            Label lblSearch = new Label() { Text = "Enter bank to search for: " };

            Button btnSearch = new Button() { Text = "Search" };

            BulletedList resultsList = new BulletedList();

            TextBox tbSearchCriteria = new TextBox();

     

            public ViewImpl()

            {

                this.presenter = new Presenter(this);

            }

     

            protected override void CreateChildControls()

            {

                this.Controls.Clear();

                this.btnSearch.Click += new EventHandler(btnSearch_Click);

                this.Controls.Add(this.lblSearch);

                this.Controls.Add(this.tbSearchCriteria);

                this.Controls.Add(this.btnSearch);

                this.Controls.Add(this.resultsList);

                this.ChildControlsCreated = true;

            }

     

            void btnSearch_Click(object sender, EventArgs e)

            {

                this.presenter.Search();

            }

     

            #region IView Members

     

            public string SearchCriteria

            {

                get { return this.tbSearchCriteria.Text; }

            }

     

            public List<string> Results

            {

                set

                {

                    this.resultsList.Items.Clear();

     

                    List<string> results = new List<string>(value);

     

                    foreach (string r in results)

                    {

                        this.resultsList.Items.Add(r);

                    }

                }

            }

            #endregion

        }

    WPF Implementation

     

     

        public partial class Client : Window, IView

        {

            SearchPresenter presenter;

     

            public Client()

            {

                this.presenter = new SearchPresenter(this);

     

                InitializeComponent();

            }

     

            private void button1_Click(object sender, RoutedEventArgs e)

            {

                this.presenter.Search();

            }

     

            #region ISearchView Members

     

            public List<string> Results

            {

                set

                {

                    this.listBox1.Items.Clear();

     

                    foreach (SearchResult r in value)

                    {

                        this.listBox1.Items.Add(r.ToString());

                    }

                }

            }

     

            public string SearchCriteria

            {

                get { return this.tbSearchCriteria.Text; }

            }

     

            #endregion

        }

     

     


     

    Links

    §  http://blog.vuscode.com/malovicn/archive/2007/11/04/model-view-presenter-mvp-design-pattern-close-look-part-2-passive-view.aspx

    §  http://weblogs.asp.net/bsimser/archive/2006/07/18/Model_2D00_View_2D00_Presenter-Pattern-with-SharePoint-Web-Parts.aspx

    §  http://geekswithblogs.net/Podwysocki/archive/2007/12/20/117881.aspx

    §  http://en.wikipedia.org/wiki/Model_View_Presenter

    §  http://en.wikipedia.org/wiki/Mock_object

    §  http://msdn.microsoft.com/en-us/magazine/cc188690.aspx

    §  http://www.martinfowler.com/eaaDev/ModelViewPresenter.html 

    §  http://en.wikipedia.org/wiki/Factory_method

  • Windows Mobile dev - Emulator network connection

    Recently I've had to do a spot of Windows Mobile dev, part of which requires the mobile app to call a webservice, simple enough you may think. Well it is once you can figure out how to get the emulator to use the host network connection.

    So here's how I got the emulator to use the host's network:

    1. Firstly, deploy your smart device project to the emulator as normal
    2. Once deployed, open the Device Emulator Manager in VS (Tools > Device Emulator Manager)
    3. You should see next to one of the types of emulator you can run, a little green arrow indicating this is the emulator currently running
    4. Right click on that emulator, and select 'Cradle'
    5. A bunch of ActiveSync (by the way you need ActiveSync) messages will pop up, just dismiss them. A guest partnership is all you need.
    6. ActiveSync will now treat the emulator as a real physical mobile device and give it access to the host's network access via a DMA channel.
    7. The Emulator should pop up with a notification to indicate it has network access
    8. Ensure if you're using a proxy, to set that information in the emulator's network settings
    9. You're done!

     

     

  • Installing SmartPart for Sharepoint (with a dash of WCF) 2 of 2

    In my last post I explained (as countless other blogs have) how to install SmartPart on SharePoint and get a user control to display inside it. Now I'm going to try and give you a few pointers on some of the pitfalls involved in trying to get your WebPart to call a WCF service (short and sweet really).

    First and rather obviously, move the system.serviceModel element under the configuration root element in your website's web.config. This means your webpart will have access to the binding and endpoint information when you make the service call.

      <system.serviceModel>
        <bindings>
          <basicHttpBinding>
            <binding name="BasicHttpBinding_IRegistrationService" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard" maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536" messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered" useDefaultWebProxy="true">
              <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384"/>
              <security mode="None">
                <transport clientCredentialType="None" proxyCredentialType="None" realm=""/>
                <message clientCredentialType="UserName" algorithmSuite="Default"/>
              </security>
            </binding>
          </basicHttpBinding>
        </bindings>
        <client>
          <endpoint address="http://localhost:8732/Design_Time_Addresses/POC/RegistrationService/" binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IRegistrationService" contract="RegistrationService.IRegistrationService" name="BasicHttpBinding_IRegistrationService"/>
        </client>
      </system.serviceModel>
     

    When I tried calling the service from inside my user control (wrapped up inside the SmartPart) I got a wierd exception telling me 'Request for the permission of type 'System.Net.WebPermission' failed', something to do with permissions my keen developer instinct told me.

    It turns out that your SharePoint's default web.config stipulates only minimal trust for all user assemblies executing within its context (this is controlled by the CLR's CAS security block). To fix it, i set my website's trust level to 'Full'.

        <trust level="Full" originUrl="" />

    This is obviously not reccommended for blatantly obvious security reasons but for my test purposes on my personal little sharepoint box it did the job! Now I can call WCF services in glorious technicolour.

    Hope that helps.

     

     

     

  • Installing SmartPart for Sharepoint (with a dash of WCF) 1 of 2

    It's a friday afternoon and I've just spent the better part of the day banging my head against SharePoint, so in a break from tradition I've decided to blog about how I got it working.

    For those who don't know, SmartPart is a funky little Web Part for SharePoint. It allows lazy people (such as myself) to develop ASP.NET user controls with Visual Studio's WYSIWYG editor and then wrap them up as though they were a true orthodox WebPart. As I'm sure you're all aware, web parts are in actuality custom controls which require the developer to write code to output the presentational HTML, so SmartPart can save you a gret deal of time and effort.

    1) So firstly, download SmartPart from codeplex.com/smartpart

    2) Run the installer which checks you have WSS and all that jazz

    3) Stick the SmartPart assembly in the GAC (c:\windows\assembly)

    4) Activate the feature to your chosen site collection

    5) Edit a test page and add a web part

    6) Select Smart Part from the web part gallery dialogue you're presented with

    Now you may be luckier than I, but at this point for the me SharePoint fell over and complained that the SmartPart webpart was not trusted. So you have to go into the web.config for your website and add the SmartPart.dll as a SafeControl.

          <SafeControl Assembly="ReturnOfSmartPart, Version=1.3.0.0, Culture=neutral, PublicKeyToken=9f4da00116c38ec5" Namespace="SmartPart" TypeName="*" Safe="True" AllowRemoteDesigner="True" />
     

    7) Try to add the SmartPart webpart again and this time it should work.

    8) Next add two dirctories to your website; UserControls and Bin. The former is where your ASCX user controls (and their code-behind) will reside, and the latter is where the corresponding user control assembly will sit (if you have any classes/interfaces which are not control code files, for example WCF proxies).

    9) Now you should be in a state where you can put user control ASCXs etc on your website and SmartPart can find them.

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

    In my next blog I will explain some of subtlteties involved in calling a WCF service from within the SmartPart webpart. Hope this was of use to someone.

     

     

  • Shiny new blog

    This is my new MSDN blog. Work/Life balance permitting (lol) I'll update this with dev hints, tips and tricks which will hopefully elucidate a few people.

© 2009 Microsoft Corporation. All rights reserved. Terms of Use  |  Trademarks  |  Privacy Statement
Microsoft
Page view tracker