The other day I was working on a site which required a pager, so I searched around a bit and I a pagerby Gunnar Peipman that looked promising. I found a few others but decided against them. Some of them loaded all of the data into memory and then paged from there, and others just flat out didn't work! In any case I had a good experience with Gunnar's. I wanted to take what Gunnar had and create a view helper using my custom view helpers. Along the way I found myself writing some code using the TagBuilderclass that just didn't sit well with me. Take a look at the snippet below which.
01TagBuilder startTag = new TagBuilder("a");
02startTag.Attributes.Add("href", string.Format("{0}/{1}", this.UrlPrefix, 1));
03startTag.SetInnerText("<<");
04startTag.Attributes.Add("title", "first page");
05httpResponse.Write(startTag.ToString(TagRenderMode.Normal));
06 
07TagBuilder previous = new TagBuilder("a");
08previous.Attributes.Add("href", string.Format("{0}/{1}", this.UrlPrefix, this.CurrentPage - 1));
09previous.SetInnerText("<");
10previous.Attributes.Add("title", "previous page");
11httpResponse.Write(previous.ToString(TagRenderMode.Normal));
I didn't like the fact that I had to make a bunch of calls to the tag builder to build the HTML for me, it was just uglier than what I wanted. So I decided to create a new tag builder which places an Fluent interface on top of it (ok, maybe its just method chaining). The end result was the FluentTagBuilderclass. I couldn't extend TagBuilderbecause I wanted to change the return types, so instead I created the class to just contain one and to just pass the calls through to it. What I did was to declare all the same properties and methods that the TagBuilder had, but just change the ones who returned void to return the same object itself. So for example I created methods like.
01public FluentTagBuilder AddCssClass(string value)
02{
03    this.TagBuilder.AddCssClass(value);
04    return this;
05}
06 
07public FluentTagBuilder SetInnerHtml(string innerHtml)
08{
09    this.TagBuilder.InnerHtml = innerHtml;
10    return this;
11}
With this I can chain different method calls together and create code which looks better. If you've used jQuerythen you are used to this. With this in place I was able to convert the snippet above into the following.
01FluentTagBuilder startTag =
02    new FluentTagBuilder("a")
03    .AddAttribute("href", string.Format("{0}/{1}", this.UrlPrefix, 1))
04    .SetInnerText("<<")
05    .AddAttribute("title", "first page");
06 
07httpResponse.Write(startTag.ToString(TagRenderMode.Normal));
08 
09FluentTagBuilder previous =
10    new FluentTagBuilder("a")
11    .AddAttribute("href", string.Format("{0}/{1}", this.UrlPrefix, this.CurrentPage - 1))
12    .SetInnerText("<")
13    .AddAttribute("title", "previous page");
14 
15httpResponse.Write(previous.ToString(TagRenderMode.Normal));
To me this is a lot easier to read, and to create. If you agree you can grab the class and include it in your projects. Links to full source files are below.
  1. FluentTagBuilder.cs
  2. Pager.cs
Sayed Ibrahim Hashimi

Comment Section

Comments are closed.


Today a friend of mine asked me to explain (via email) a few things to another developer regarding some things I have done with the Entity Framework (EF). I figured since I already typed it up I might as well share it here as well. So here it is.

I have had 2 issues with using EF4 which I have found creative and effective work around for.

Externalizing filters

The first issue, which also exists when using other frameworks, is that you end up with an explosion of methods (and usually a lot of duplicated code). For instance let’s say you have a table to store users. This table has an ID, and Email field and, and let’s and OpenIdUrl. So you end up with the following methods.

1User GetUserById(long id)
2 
3User GetUserByEmail(string email)
4 
5User GetUserByOpenIdUrl(string openIdUrl)

Usually you’ll find that each of these methods have the exact same implementation except a different where clause. Now there is a bigger problem in the fact that you cannot anticipate everything that the user may want to filter on. Because of this and the dynamic nature of IQueryable I have employed a technique using Expression Trees to allow the user to declare the exact filter to be used via a lambda expression. So for the users it’s very slick. For example I could create the following method

01public User GetUser(Expression<func<user, bool="">> filter)
02{
03    if (filter == null)
04    {
05        filter = Const<user>.LinqExpression.LinqExpressionFuncAlwaysTrue;
06    }
07 
08    User foundUser = null;
09    using (InlineTasksContext dbContext = new InlineTasksContext())
10    {
11        dbContext.Connection.Open();
12        foundUser = dbContext.Users.Where(filter).SingleIfExists();
13    }
14 
15    return foundUser;
16}</user></func<user,>

In this case I’m allowing the user to pass in a filter that is applied to the query. Here is how I could implement those three if I chose to as well.

01public User GetUserById(long id)
02{
03    return this.GetUser(user => user.Id == id);
04}
05public User GetUserByEmail(string email)
06{
07    if (email == null) { throw new System.ArgumentNullException("email"); }
08 
09    return GetUser(user => user.Email == email);
10}
11public User GetUserByOpenIdUrl(string openIdUrl)
12{
13    if (string.IsNullOrEmpty(openIdUrl)) { throw new ArgumentNullException("openIdUrl"); }
14 
15    return GetUser(user => user.OpenIdUrl == openIdUrl);
16}

Note in the first method I am using some other helpers I created. Specifically the Const.LinqExpression.LinqExpressionFuncAlwaysTrue as well as the SingleIfExists

extension method. I use the AlwaysTrue expression so that way I don’t have to be worried about doing an if and having to maintain 2 select statements. And the other (SingleIfExists) is used to just return null instead of blowing up if no elements exist in the sequence.

Since they are not the purpose of this email I’ve just put them at the bottom so that you can read if you are interested.

As Keith mentioned to me a while back Expression trees are not serializable so you still end up with this problem if you are using a service based solution. But you could try and use the sample Expression Tree Serialization to take care of this for you, I’ve never tried it, but it’s on my TODO list.

.Include

My next issue is that you are forced to declare what navigation properties (i.e. table links) should be included in the query. This is done using the .Include method. So back to our GetUser example, how can a framework know what tables values should be extracted for? The end result is that the framework creator just includes a bunch of tables and 90% of the time the result is just wasted resources because the other data is never touched. Better is to provide a default which only includes the most commonly used tables and another method that allows them to specify what they want. Here is a sample for a GetTasksByUserId method

01public IList<task> GetTasksByUserId(long userId, IEnumerable<string> includeList)
02{
03    using (InlineTasksContext dbContext = new InlineTasksContext())
04    {
05        var result = (from t in dbContext.Tasks
06                        .Include(includeList)
07                        .Where(t=>t.User.Id == 1)
08                        select t)
09                        .ToList();
10        return result;
11    }
12}
13 In this example I’m using an extension method for.Include which is defined as follows.
14public static ObjectQuery<t> Include<t>(this ObjectQuery<t> query, IEnumerable<string> includes)
15{
16    if (query == null) { throw new System.ArgumentNullException("query"); }
17 
18    if (includes != null)
19    {
20        foreach (string include in includes)
21        {
22            query.Include(include);
23        }
24    }
25    return query;
26}</string></t></t></t></string></task>

So the idea is to create a framework which is both robust and easy to use, but at the same time is not overly assumptive about what the users want. I think a lot more can be done with EF and its dynamic nature.

Does that cover what you were intending Keith? Any questions/comments please send them my way.

Here are those methods I mentioned above.

01public static class LinqExtensions
02{
03    public static T SingleIfExists<t>(this IQueryable<t> query)
04    {
05        if (query == null) { throw new System.ArgumentNullException("query"); }
06 
07        T result = default(T);
08        if (query.Count() > 0)
09        {
10            result = query.Single();
11        }
12 
13        return result;
14    }
15}
16//----------------------------------------------------------------------------------------------------
17public class Const<t>
18{
19    public static class Predicate
20    {
21        public static Predicate<t> AlwaysTrue
22        {
23            get
24            {
25                return x => true;
26            }
27        }
28 
29        public static Predicate<t> AlwaysFalse
30        {
31            get
32            {
33                return x => false;
34            }
35        }
36    }
37 
38    public class LinqExpression
39    {
40        public static Expression<func<t, bool="">> LinqExpressionFuncAlwaysTrue
41        {
42            get
43            {
44                return x => true;
45            }
46        }
47    }
48}</func<t,></t></t></t></t></t>
Sayed Ibrahim Hashimi

Comment Section

Comments are closed.


The story around routing in ASP.NET MVC is pretty good. When a resource is requested the action that it is routed to is determined and the parameters to the action are initialized. Counter to that when you build a link you specify the argument values and it creates the url for you. So if your routes happen to change your application shouldn’t be bothered by that. One area which can be problematic for this is if you are making any ajax requests. What I’ve done to minimize the impact of route changes to Ajax requests is to have the script make a call to determine the correct route. In the most trivial case this is extremely easy. You call an action, which has a known route, passing into it the name of the action and controller. It returns to you the url for the route. This works really good, but the problem is when your routes have parameters, how do you handle those?

First let’s take a look at the Javascript and then the definition of the action method which it calls.

01// wire up the event for the enter button
02$("#searchText").keypress(function (event) {
03    if (event.keyCode == 13) {
04        // grab the text that is inside the box
05        var text = $("#searchText").val();
06 
07        var routData = {
08            controllerName: 'Search',
09            actionName: 'Search',
10            paramValues: "{ criteria: '" + text + "' }"
11        };
12 
13        $.ajax({
14            url: "/Home/MapRoute",
15            data: routData,
16            success: function (data) {
17                window.location.href = data;
18            },
19            error: function (data) {
20                alert('there was a failure on the internets');
21            }
22        });
23 
24    }
25});

Here I am building a Javascript object named routeData. This is declared in JSON. One thing to pay attention to is the fact that the value for paramValues is a string containing JSON. This is passed to the controller action.

I’m using jQuery to make an Ajax request to /Home/MapRoute. This maps to the method shown below.

01public JsonResult MapRoute(string actionName, string controllerName, string paramValues)
02{
03    JavaScriptSerializer jss = new JavaScriptSerializer();
04 
05    Dictionary<string, string=""> parameters = jss.Deserialize<dictionary<string, string="">>(paramValues);
06 
07    RouteValueDictionary rd = new RouteValueDictionary();
08    foreach (string key in parameters.Keys)
09    {
10        rd.Add(key, parameters[key]);
11    }
12 
13    UrlHelper urlHelper = new UrlHelper(this.Request.RequestContext);
14    string url = urlHelper.Action(actionName, controllerName, rd);
15 
16    return Json(url, JsonRequestBehavior.AllowGet);
17}</dictionary<string,></string,>

Here I’m using the JavaScriptSerializer to convert the JSON string into a dictionary, with string as key and value. I use that dictionary to create a RouteValueDictionary which is passed, along with other parameters, into the UrlHelper to generate the url. When you return the Json result you must specify JsonRequestBehavior.AllowGet, otherwise a 500 internal service error will be returned. I think this is new with ASP.NET 2.

When the action method returns, you can use that url. The drawback to this approach is that you will make an extra request to determine the url, but you will be sure that those urls are correct. Also you could cache the results with Output Caching since the routes won’t change.

Sayed Ibrahim Hashimi


Comment Section

Comments are closed.


Have you seen those text boxes on the web that have a hint contained inside of it and wondered how you could implement that? It's pretty easy with jQuery, and there already exist some plugins that you can use, for example here is one. When I set out to do this I didn’t even look to see what was out there because I wanted to write a jQuery plugin, but the solution that I can up with is not that different from that one.

Here is how I wanted the plugin to behave

  1. Add a specified hint to the text box, if the input element was not focused and empty
  2. When the text box was focused, the hint should disappear
  3. When a form is submitted all hints should be removed prior to ensure that they are not incorrectly submitted

First what I did was to create the a file named jquery.sedotech.inputWithHint.js. You should name your plugins using this naming convention

jquery.customString.pluginName.js

Here is the source for the plugin

01(function ($) {
02    var hintClassName = 'inputWithTextHint';
03 
04    $.fn.addHint = function (hint) {
05        var filteredSet = this.filter('input:text, textarea');
06        filteredSet.each(function () {
07            // In here 'this' refers to an individual element
08            doAddHint($(this), hint);
09        });
10 
11        // Find all forms and update the pre post to remove the hint
12        $('form input:submit').click(function () {
13            $('input:text, textarea').each(function () {
14                if ($(this).hasClass(hintClassName) && $(this).attr('hint')
15                && $(this).val() == $(this).attr('hint')) {
16                    $(this).val('');
17                }
18            });
19        });
20    }
21 
22    function doAddHint(target, hint) {
23        // Only add hint if the target is empty
24        if (target.val() == '') {
25            addHintToInput(target, hint);
26 
27            target.focus(function () {
28                // If the target has the hint class on it then a hint must be showing
29                //  when hint is showing put cursor at the begining
30                if ($(this).hasClass(hintClassName)) {
31                    // remove the hint
32                    $(this).val('');
33                    // remove class
34                    $(this).removeClass(hintClassName);
35                }
36            });
37 
38            target.blur(function () {
39                // If no text then add hint class back
40                if ($(this).val() == '') {
41                    addHintToInput(target, hint);
42                }
43            });
44        }
45    }
46 
47    function addHintToInput(target, hint) {
48        target.val(hint);
49        target.addClass(hintClassName);
50        // add attribute to the target to store hint
51        target.attr('hint', hint);
52    }
53})(jQuery);
Some things to take note of. When you are creating a plugin in you should use the pattern
1(function ($) {
2    // plugin code here
3})(jQuery);

Take note of the ($) as the parameter and (jQuery) at the end. What is happening here is that you are defining an anonymous function declaring a parameter named $ and then invoking that function passing in the jQuery object. You do this because when you are authoring plugins the $ variable is not available, you have to use the other alias jQuery, but that’s just way too difficult. If you use the pattern you are ensured that the $ alias is available and it won’t conflict with other Javascript libraries.

Beyond this all I’m doing is filtering the list of items which are passed in, with the expression var filteredSet = this.filter('input:text, textarea'), to make sure that the plugins doesn’t touch elements which it is not familiar with modifying. After I add the hint, by calling doAddHint on each element in the filtered set, I make sure that the forms on the page are not submitted with those hints.

Resource Links

Sayed Ibrahim Hashimi


Comment Section

Comments are closed.


I'm working on an application right now which uses some mock classes which were "hand written" instead of using a mock framework. I haven't had much experience with using mock frameworks, but I've wanted to learn more about them. There are many mock frameworks out there, I chose to use moq because the test cases for ASP.NET MVC use moq. What I wanted to do was replace the mock class that I created with a moq class. If you have ever created mock classes before then you probably know that they are pretty annoying to maintain. What I mean is that if you add a method/property to the interface which the mock class implements then you have to update the mock just to get it to build. This is annoying and kinda makes people not to use the mock which then ends up in ignoring/commenting out test cases. To avoid all of this most mock frameworks, including moq, just require you to specify behavior for methods/properties which you are ready to exercise in your test cases. Now I’d like to show you the mock class that I had. This interface that it is mocking is used to abstract the data store.

001internal class MockModelContext :IModelContext
002{
003    public User CreateUser(User user)
004    {
005        // if id is not set, set it and just return it
006        if (user.Id <= 0)
007        {
008            user.Id = 1;
009        }
010 
011        return user;
012    }
013 
014    public User GetUserByEmail(string email)
015    {
016        if (string.IsNullOrEmpty(email)) { throw new ArgumentNullException("email"); }
017 
018        User user = CreateDummyUser();
019        user.Email = email;
020 
021        return user;
022    }
023 
024    public User GetUser(Expression<func<user, bool="">> filter)
025    {
026        return CreateDummyUser();
027    }
028 
029    public IList<task> GetRecentTasks()
030    {
031        IList<task> tasks = new List<task>()
032        {
033            new Task()
034            {
035                CreatedDate = new DateTime(2010,1,1,1,1,1),
036                CreatorId = 1,
037                //Description ="Description 01 here",
038                Headline="Headline 01 here",
039                Id = 1,
040                LastEditedDate= new DateTime(2010,1,1,1,1,1),
041                LastEditOwnerId=1,
042                Name = "Name here",
043                NumViews = 3,
044                Script = @"<scripthere>script</scripthere>",
045                // TODO: Tags
046                // TODO: TaskComments
047                User = new User()
048                {
049                    Email ="one@hotmail.com",
050                    FirstName="First",
051                    Id=2,
052                    LastName="Last",
053                    MiddleName="Middle",
054                }
055            },
056            new Task()
057            {
058                CreatedDate = new DateTime(2010,1,1,1,1,1),
059                CreatorId = 1,
060                //Description ="Description 02 here",
061                Headline="Headline 02 here",
062                Id = 1,
063                LastEditedDate= new DateTime(2010,1,1,1,1,1),
064                LastEditOwnerId=1,
065                Name = "Name here",
066                NumViews = 3,
067                Script = @"<scripthere>script2</scripthere>",
068                // TODO: Tags
069                // TODO: TaskComments
070                User = new User()
071                {
072                    Email ="one@hotmail.com",
073                    FirstName="First",
074                    Id=2,
075                    LastName="Last",
076                    MiddleName="Middle",
077                }
078            }
079        };
080 
081        return tasks;
082    }
083    protected internal User CreateDummyUser()
084    {
085        User user = new User()
086        {
087            Email = "email",
088            FirstName = "First",
089            LastName = "Last",
090            MiddleName = "Middle"
091        };
092 
093        return user;
094    }
095    public User GetUserByOpenIdUrl(string openIdUrl)
096    {
097        throw new NotImplementedException();
098    }
099    public IList<task> GetRecentTasks(IEnumerable<string> includeList)
100    {
101        throw new NotImplementedException();
102    }
103    public Task AddTask(Task task)
104    {
105        throw new NotImplementedException();
106    }
107    public User GetUserById(long id)
108    {
109        User user = this.CreateDummyUser();
110        user.Id = id;
111 
112        return user;
113    }
114    public User SaveUser(User user)
115    {
116        throw new NotImplementedException();
117    }
118    public Task GetTaskById(long id)
119    {
120        throw new NotImplementedException();
121    }
122}</string></task></task></task></task></func<user,>

Take notice of the methods which just throw a NotImplementedException, these are methods that I just added to the interface and haven’t yet written test cases for. (Yeah I know I’m not following true TDD, but I never claimed to be either). Now you can compare that to these methods which use moq to create the mock.

001private Mock<imodelcontext> CreateMockModelContext()
002{
003    var context = new Mock<imodelcontext>();
004 
005    context.Setup(c => c.CreateUser(It.IsAny<user>()))
006        .Returns<user>(user =>
007        {
008            if (user.Id <= 0)
009            {
010                user.Id = 1;
011            }
012            return user;
013        });
014 
015    context.Setup(c => c.GetUserByEmail(It.IsAny<string>()))
016        .Returns<string>(email =>
017            {
018                if (email == null) { throw new ArgumentNullException("email"); }
019 
020                User user = this.CreateDummyUser();
021                user.Email = email;
022 
023                return user;
024            }); ;
025 
026    context.Setup(c => c.GetUserById(It.IsAny<long>()))
027        .Returns<long>(id =>
028        {
029            User user = new User();
030            user.Id = id;
031            return user;
032        });
033 
034    context.Setup(c => c.GetRecentTasks())
035        .Returns(() =>
036        {
037            IList<task> tasks = new List<task>()
038            {
039                new Task()
040                {
041                    CreatedDate = new DateTime(2010,1,1,1,1,1),
042                    CreatorId = 1,
043                    //Description ="Description 01 here",
044                    Headline="Headline 01 here",
045                    Id = 1,
046                    LastEditedDate= new DateTime(2010,1,1,1,1,1),
047                    LastEditOwnerId=1,
048                    Name = "Name here",
049                    NumViews = 3,
050                    Script = @"<scripthere>script</scripthere>",
051                    // TODO: Tags
052                    // TODO: TaskComments
053                    User = new User()
054                    {
055                        Email ="one@hotmail.com",
056                        FirstName="First",
057                        Id=2,
058                        LastName="Last",
059                        MiddleName="Middle",
060                    }
061                },
062                new Task()
063                {
064                    CreatedDate = new DateTime(2010,1,1,1,1,1),
065                    CreatorId = 1,
066                    //Description ="Description 02 here",
067                    Headline="Headline 02 here",
068                    Id = 1,
069                    LastEditedDate= new DateTime(2010,1,1,1,1,1),
070                    LastEditOwnerId=1,
071                    Name = "Name here",
072                    NumViews = 3,
073                    Script = @"<scripthere>script2</scripthere>",
074                    // TODO: Tags
075                    // TODO: TaskComments
076                    User = new User()
077                    {
078                        Email ="one@hotmail.com",
079                        FirstName="First",
080                        Id=2,
081                        LastName="Last",
082                        MiddleName="Middle",
083                    }
084                }
085 
086            };
087            return tasks;
088        });
089 
090    return context;
091}
092protected internal User CreateDummyUser()
093{
094    User user = new User()
095    {
096        Email = "email",
097        FirstName = "First",
098        LastName = "Last",
099        MiddleName = "Middle"
100    };
101 
102    return user;
103}</task></task></long></long></string></string></user></user></imodelcontext></imodelcontext>

Since I’m just mocking methods all I’m really doing here is using the moq Setup method (formerly known as Expect), and the Returns method to implement the behavior that I needed. The key to note here is that if you need to access the parameter(s) passed into the method, then you will have to used Returns and pass in a lambda expression that contains the behavior. In that lamdba you can name the parameter anything you want, but I would suggest you name it the same name that the method you are mocking names it. This makes it much more understandable what you are actually doing.

Sayed Ibrahim Hashimi


Comment Section

Comments are closed.


<< Older Posts | Newer Posts >>