I am working on finishing an open source project and releasing a V1.0 of my Nucleo project (http://www.codeplex.com/nucleo). I came across an example that I can use to illustrate testability. Take a look at the following component:
public class WebTraceLogManager : ILogManager
{
private Page GetPage()
{
if (HttpContext.Current.Handler is Page)
return (Page)HttpContext.Current.Handler;
else
return null;
}
public void LogError(Exception ex, string source)
{
Page page = this.GetPage();
if (page != null)
page.Trace.Warn(source, ex.Message, ex);
}
public void LogMessage(string message, string source)
{
Page page = this.GetPage();
if (page != null)
page.Trace.Write(source, message);
}
}
Notice that this component is self-contained; the Page class reference is obtained from a static member. This static member must be supplied at testing time if I want to be able to run outside of a unit test (unless I'm using a web testing product like WATIN or WebAii by Telerik). With a general testing product like Moq, static classes can't be typically mocked. One product that I know of, TypeMock, does have the ability to write a unit test for this class, and it would be something like:
[Test]
public void TracingErrorsWorksOK()
{
//Arrange
var page = Isolate.Fake.Instance<Page>();
var contextFake = Isolate.Fake.Instance<HttpContext>();
Isolate.WhenCalled(() => HttpContext.Current).WillReturn(contextFake);
Isolate.WhenCalled(() => contextFake.Handler).WillReturn(page);
var traceContext = Isolate.Fake.Instance<TraceContext>();
Isolate.WhenCalled(() => page.Trace).WillReturn(traceContext);
//Act
var manager = new WebTraceLogManager();
manager.LogError(new Exception(), "Test");
//Assert
Isolate.Verify.WasCalledWithAnyArguments(() => { traceContext.Warn(null, null, null); });
}
TypeMock has the ability to mock static method calls using Isolate.WhenCalled; furthermore, you can see that it takes a good bit in order to fake the ability to write to the trace output. We have to create a mock HttpContext, and ensure that HttpContext.Current returns our faked implementation of HttpContext. Furthermore, we have to ensure the Handler property returns a reference to a faked Page class reference, which we also have to create a fake for. Furthermore, the Page class has to use the Trace property (of type TraceContext), which if we manually constructed would also use HttpContext. Because I created a fake, no actual methods will get called (including the constructor), which is good because if I were to write my own fake, who knows how many features I would have to implement to ensure writing to the TraceContext doesn't call an error? TraceContext could use a property on HttpContext that I would have to guarantee be there, which may also use another property that I have to handle, and so on. Writing fakes in TypeMock makes that a lot easier.
But there is an alternative way, which requires a little restructuring. While it doesn't solve all of the problems of testability, it makes it a little more testable by adding a constructor:
public class WebTraceLogManager : ILogManager
{
private Page _page = null;
public WebTraceLogManager(Page page) { _page = page; }
public void LogError(Exception ex, string source)
{
if (_page != null)
_page.Trace.Warn(source, ex.Message, ex);
}
public void LogMessage(string message, string source)
{
if (_page != null)
_page.Trace.Write(source, message);
}
}
Now, anything that's passed in can be used, so outside of the unit test, we can do something a little more simple like:
[Test]
public void TracingErrorsWorksOK()
{
//Arrange
var page = Isolate.Fake.Instance<Page>();
var traceContext = Isolate.Fake.Instance<TraceContext>();
Isolate.WhenCalled(() => page.Trace).WillReturn(traceContext);
//Act
var manager = new WebTraceLogManager(page);
manager.LogError(new Exception(), "Test");
//Assert
Isolate.Verify.WasCalledWithAnyArguments(() => { traceContext.Warn(null, null, null); });
}
Now we can reduce the number of fakes we need; we need a fake Page implementation (though we can directly instantiate Page as it requires no specialty implementations depending on what properties you need). The Trace property though, needs a reference to HttpContext in the constructor, so any mocking framework needs to be able to mock HttpContext in order to create the fake for the TraceContext class. But you can see the amount of reduced dependencies.
To take this one step further, we can do this to add another level of testability, and make the faking process even easier:
public class WebTraceLogManager : ILogManager
{
private ITracer _t = null;
public WebTraceLogManager(ITracer t) { _t = t; }
public void LogError(Exception ex, string source)
{
if (_t != null)
_t.Warn(source, ex.Message, ex);
}
public void LogMessage(string message, string source)
{
if (_t != null)
_t.Write(source, message);
}
}
Now we have an interface to deal with. Anything implementing this interface can be used. To use the page implementation in the web site, we can create an additional wrapper class like:
public class PageTracing : ITracing
{
private Page _page = null;
public PageTracing(Page page) { _page = page; }
//ITracing members
public void Write(..) { _page.Trace.Write(...); }
public void Warn(..) { _page.Trace.Warn(..); }
}
And then another fake implementation that does:
public class FakeTracing : ITracing
{
private List<Message> _traces = new List<Message>();
public List<Message> Messages { get { return _traces; } }
public void Write(..) { _traces.Add(new Message(..)); }
public void Warn(..) { _traces.Add(new Message(..)); }
}
So the fake implementation exposes the collection of messages; you can pass in a reference to the test as in:
[Test]
public void TracingErrorsWorksOK()
{
//Arrange
FakeTracing tracing = new FakeTracing();
//Act
var manager = new WebTraceLogManager(tracing);
manager.LogError(new Exception(), "Test");
//Assert
Assert.AreEqual(1, tracing.Messages.Count);
Assert.AreEqual("Test", tracing.Messages[0].Message);
}
So you can see the immediate benefit; the interface buys us the ability to use a fake that exposes the inner contents directly for testing purposes, while using the PageTracing class in production web environment that continues to use the Page approach we need. So the benefits are many, also including the ability to use other testing frameworks outside of just TypeMock, since we can pass in an interface implementation.
For some reason, I couldn't figure out why that the NeedDataSource event wasn't firing correctly. I spent hours trying to figure out the solution, and this forum post really helped me to solve the issue: http://www.telerik.com/community/forums/reporting/telerik-reporting/needdatasource-event-not-firing-when-updating-the-reportviewer.aspx. When using stored procedures, Telerik stores datasets in the component designer within the report, as well as their table adapters generated by a strongly typed dataset. The issue I was having was related to a few things: assigning the data table to the report's data source property in the needdatasource event (I was doing something similar, but wasn't in the end passing the table to the datasource property). Additionally, assigning the DataSource property to null in the constructor helped too; I'm not sure why, but it seemed that the report wanted the data source in the constructor, or else it didn't work correctly.
Note: I didn't bind the sqldataadapter to the report, like the example illustrated.
Like web forms, MVC allows you to customize the building blocks for developing in MVC. Extension helpers are so easy to write because all it takes is an extension method like the following:
public static class MyExtensions
{
public static string CustomHiddenField(this HtmlHelper html, int key)
{
return string.Format("<input type='hidden' value='{0}' />", key);
}
}
And now we have our extension that can be used within an MVC app (as long as the namespace is declared in an Imports statement, or in the configuration file):
<%= Html.CustomHiddenFIeld(5) %>
And voila, this requires less work and allows us to change one implementation to change all of the references (in case we wanted to switch it to another mechanism for storage, say a javascript block with a JSON object to store the key, for example).
That was a brief example to get the picture, and a picture of what you see with most custom helpers. But, I am tending to dislike the approach this implementation takes; while this example is simple, other html helpers in the .NET MVC framework tend to look like the BeginForm statement in the following:
BeginForm(this HtmlHelper htmlHelper, string actionName, string controllerName, RouteValueDictionary routeValues, FormMethod method, IDictionary<string, object> htmlAttributes);
You get the picture; with multiple overloads, you may end up inserting values in the wrong object (as some overload take an object for the routeValues and html attributes collection). It may be easier to use an alternative approach, as the exact method overload that would be very convenient to have is missing. Hence, a better design can be to take advantage of the fluent interface approach to designing a UI. As an alternative to the form design above, I created a component that worked like the following:
public class HtmlFormBuilder
{
private HtmlForm _form = new HtmlForm();
public HtmlFormBuilder Action(string actionName, RouteValueDictionary routeValues)
{
return Action(actionName, null, routeValues);
}
public HtmlFormBuilder Action(string actionName, string controllerName, RouteValueDictionary routeValues)
{
_form.ActionName = actionName;
_form.ControllerName = controllerName;
_form.RouteValues = routeValues;
return this;
}
public HtmlFormBuilder HtmlAttributes(object attributes)
{
TagAttributeReader reader = new TagAttributeReader();
reader.ReadAttributes(attributes);
_form.HtmlAttributes = reader.Attributes;
return this;
}
public HtmlFormBuilder HtmlAttributes(IDictionary<string, object> attributes)
{
_form.HtmlAttributes = attributes;
return this;
}
public HtmlFormBuilder Method(FormMethod method)
{
if (_form.HtmlAttributes == null)
_form.HtmlAttributes = new Dictionary<string, object>();
_form.HtmlAttributes["method"] = method.ToString();
return this;
}
public override string Render()
{
..
}
}
A form builder uses a custom object that represents the HtmlForm in the underlying implementation. The builder assigns values within the form, and creates the fluent interface by returning an instance of the builder in each method except for Render. So the action method assigns action values to the underlying object, simply by passing the params on to the object. Adding overloads makes it more convenient to the user.
The Render method is the final part of the process, which returns a string to get output to the browser. The rendering process can use a TagBuilder or StringBuilder to create the form statement and return it to the caller. Note this only generates the beginning form tag. Also, I omitted the render as the implementation I chose is not a standard implementation because it's a part of my Nucleo framework not implemented yet.
This way, we have a more fluent design; if you don't want to assign a value to something, you don't have to pass null, but can omit the method (even though it assigns null in the underlying presentation because null is the absence of a value), and strings together a response like:
<%= Html.BeginForm().Method(FormMethod.Get).Action("MyAction", null).HtmlAttributes(new { id = "formid" }).Render() %>
In this scenario, it may be more verbose, but it's more readable in my opinion. It's the approach a lot of MVC control builders are using (MvcContrib and Telerik are two that come to mind).
Recently I've been playing around with DynamSoft: an online source control product based in SQL Server. The product SourceAnywhere is a great product to use for source control because of the ability to connect anywhere online. We live in a connected world and people are connecting from across the globe; internet source control is a great way to get team development together remotely. There are a couple of solutions available, depending on the number of users and space needed. They also have other solutions, such as issue tracking and web scanning. You can check out more about SourceAnywhere and see if it fits your needs at: http://www.dynamsoft.com/Products/version-control-source-control-sourceanywhere.aspx
It works integrated into your Visual Studio with the free client download. The source control window uses the same approach you would use in Visual SourceSafe to connect to the SCM database.
The Telerik MVC grid that comes with Telerik's MVC open source framework is awesome. It really rocks; it has a lot of the features that exists within the ASP.NET AJAX framework are also in this grid implementation. Not only that, it implements MVC syntaxes for constructing the UI. Because the grid uses Action classes to render contents to the response stream, these features are available in C# only (at least fully). Below is the Telerik grid, which we'll dissect in pieces. Note that this one continuous running statement, but I'm going to break it up into sections without restating the beginning statements.
The entire API uses a fluent approach and begins with the following structure:
<% Html.Telerik().Grid(<data source>).Name("Required").Pageable(..).Sortable(..).Columns(..).Render(); %>
The approach chains methods together and supplies the parameters to the chained object, until the point of rendering occurs (note the use of the semi-colon; rendering occurs inline by performing Response.Write calls, though <%= syntax is also supported). The typical starting point is to define columns using the Columns action method; taking a reference to a variable (a factory that constructs the grid's columns), the builder appends columns to the grid. Note the use of the action approach here; this is the common theme throughout. The action method also permits using <% %> to define HTML markup inline, which is very effective and useful. Take a look at the exampel below.
<%
Html.Telerik().Grid(Model).Name("Test2")
.Columns((builder) =>
{
builder.Add((i) =>
{
%>
<%= Html.ActionLink("Edit", "Editing", new { key = i.Key }, new { @class = "t-link action-edit" })%>
<%
});
builder.Add(i => i.Key).Visible(false);
builder.Add(i => i.Name).Encoded(true).Title("Product");
builder.Add((c) =>
{
%>
Z<%= c.Sku%>
<%
}).Title("SKU");
})
Each column is chainable in nature too, and each column object returned allows you to specify the individual contents, some attributes about the column (title, visibility, whether the content is encoded, etc.), and more information. The next host of methods adds the additional features to the Grid. For instance, each major feature the grid supports has a separate action method, as shown below.
.Pageable()
.Scrollable((scroll) =>
{
scroll.Enabled(true).Height(200);
})
.Filterable()
.Sortable((sort) =>
{
sort.Enabled(true).SortMode(GridSortMode.SingleColumn);
})
Each method takes an action response, allowing you to fine-tune the individual settings. I'm using the pretty basic settings here; for instance, for Pageable and Filterable settings, simply by calling the empty version of the method enables the grid to use these features with default settings. Scrolling is enabled at a high of 200 pixel scrolling area using the action method, and sort features use an action method that allow sorting of single or multiple columns.
Other features are available too; for instance, the grid supports AJAX and can be enabled in the same approach (requiring an action to add additional details), and a slew of other feature's I'll talk about later. The final solution gets rendered to the browser at the end by calling Render, which uses the HtmlTextWriter to write the response to the browser. This all happens internally without you needing to do anything about it.
.Render();
The Telerik Grid is a very nice grid, it's free, and it's easy to use in MVC applications. Check it out if you get a chance. I'll blog more about it in later articles. Alternatively, I've written an article fully documenting the features, which is available in DevConnections magazine in March, that talks not only about the grid, but about some of the other controls, as a part 1. A part 2 will come out later detailing the other controls of the framework. It should be a good starting point for any developer, so check it out.
I'm continuing the series of blog posts on my Nucleo control suite available at http://www.codeplex.com/nucleo. This post is on the way that tags can be rendered. ASP.NET MVC has a TagBuilder class for creating a class to generate markup and render that markup to the brower. If you have used any of the HTML extensions for rendering controls like Html.TextBox, you have used the TagBuilder class. Noting that the TagBuilder class was built for MVC and is not available in 2.0 web sites or 3.5 web sites that don't reference the System.web.MVC dll, I created my own tag-building system, which comprises of a TagElement class, and a TagElementBuilder class that creates these custom tag controls. I like using the tag approach over using the previous approach of writing HTML markup using the HtmlTextWriter. For instance, compare this:
TagElement tag = TagElementBuilder.Create("INPUT");
CommonTagSettings.SetIdentifiers(tag, this.Component, this.Component.ClientID);
tag.Attributes
.AppendAttribute("type", "text")
.AppendAttribute("value", this.Component.Text ?? "")
.AppendAttribute("class", "DropDownInput")
.AppendAttribute("disabled", this.Component.Enabled ? "" : "disabled");
//To render this tag, use tag.ToHtmlString();
To the alternative approach:
writer.AddAttribute(HtmlTextWriterAttribute.Id, this.Component.ClientID); //using attributes
writer.AddAttribute("name", this.Component.ClientID); //or using string names
writer.AddAttribute("type", "text");
writer.AddAttribute("value", this.Component.Text ?? "");
writer.AddAttribute("class", "DropDownInput");
writer.AddAttribute("disabled", this.Component.Enabled ? "" : "disabled");
writer.RenderBeginTag("input");
writer.RenderEndTag(); //input
Notice while the two are very similar, the first approach is a little more readable, and the fluent API helps aid the bulk adding of attributes. While the syntax is a little verbose, I am working on an add-on to making this process a little easier (I'm still considering options). I could have made this even easier by doing the following:
TagElement tag = TagElementBuilder.Create("INPUT", new { type = "text", value = this.Component.Text ?? "", @class = "DropDownInput", disabled = "disabled" });
CommonTagSettings.SetIdentifiers(tag, this.Component, this.Component.ClientID);
This is a feature that you saw added to the ASP.NET MVC framework, the ability to read anonymous types and use their values for the underlying control. Now, through this system, it is available in 2.0 - 4.0 web forms as well. Other properties are available; for instance, TagElement also has a Styles collection that uses the same attribute approach as you see above to create a string of styles for a control. Styles can be added and the final result is rendered as the styles="" attribute for the HTML tag.
Once you have set all of your attributes, the ToHtmlString() creates a string statement for your HTML tag. Our above tag would render the following.
<input type="text" value="Some Text" class="DropDownInput" disabled="" ..></input>
This can then be written out in the Render method using the HtmlTextWriter if you like, or you can use Nucleo's rendering approach; there are a couple of different rendering options that I'll post about soon, if you would like to use Nucleo to create custom AJAX controls or extenders.
There are other features that I am still perfecting, like the ability to create a TagElementGroup and supply bulk settings at once. This makes it easier to create and work with a bulk range of objects. It's not finished, but I do have some of it's features implemented. There are two ways to create a group, supply the names of the tags, or to supply the name of a single tag, the number of items to create, and common attributes shared across all.
var tagList = TagElementBuilder.CreateGroup(new string[] { "A", "STRONG", "SPAN", "DIV" });
var tagList = TagElementBuilder.CreateGroup("A", 5,
new { Href = "http://www.yahoo.com", Target = "_blank" });
In this way, it makes working with a lot of elements easier. I'm trying to create a way to apply additional attributes in a bulk way, considering ways to apply settings to alternating elements and such.
If you've built your own custom MS ASP.NET AJAX controls or extenders, you are familiar with the description process, where a control specifies the values that it wants to send at the creation of the client-side AJAX component (consider these values as default values). ASP.NET AJAX gives you the ability to specify what you would like to pass to the client, and makes available a serializing component (JavaScriptSerializer) to perform a serialization/deserialization process to/from object and string. As an object gets converted to a string, it's then passed to the client- component's client-side property, and from there you have a responsibility to take a serialized serialized and convert it to a deserialized object (JS's equivalency to your server-side component).
In reality, you do not need to use the JavaScriptSerializer class. For instance, you can pass this to the client-side component:
descriptor.AddProperty("a", "{ id: '1', name: '2', dothis: function() { return 'this'; } }");
This is essentially what gets passed to the client when using the JavaScriptSerializer, except for we have the added capability of adding in methods to pass to the client.
get_a: function() { },
set_a: function(val) {
var o = Sys.Serialization.JavaScriptSerializer.deserialize(val);
alert(o.dothis());
}
The text "this" appears in the alert window, alerting the user of the value. So you have the ability to provide any sort of custom coding that you would like to have appear in the object that gets passed to the client side.
I and many other users constantly deal with how to make our applications perform better, and one dilemma can come from binding controls like the GridView control and many others. This problem is even a problem related to control toolsets from external vendors as well. ASP.NET isn't always adaptive to knowing when to prevent a binding of data, because that data will change in relation to some other event. For example, a control hooked up to an object data source will be bound to a control, and even though it may be tied to another control via the ControlParameter property, the ODS will still bind the control initially on load, and later when it detects a control change.
This double-binding is a database performance issue in my opinion. So how are some ways to resolve this dilemma? I recently had this issue with an older version of the Telerik RadGrid for ASP.NET (which seems to be resolved in the latest release). Say the user triggers a delete or an edit. The ODS will bind on load to load the control's data, then rebind in relation to that edit or delete event that's triggered from a button click. To prevent the first load, I will use a two prong approach:
- use a boolean that checks whether the loading is the first load for the page. This can't work on its own, I also add in
- check the Request.Form["__EVENTTARGET"] and/or Request.Form["__EVENTARGUMENT"] to see if our control is causing a postback, and cancel the initial bind (tap into the ODS selecting event and set e.Cancel = true takes care of this).
For example, you can check a specific control is a target (the __EVENTTARGET uses the control's unique name) and make sure that if it has an argument (argument for the button, or command name/argument), to stop a duplicate bind because your app is just going to rebind it later.
By the very nature of the controls, the double-bind makes sense; show the users the original data, but it doesn't know when the data changes, and has to react appropriately (event-driven model). But I like to use tricks like this to get around these very issues. Also, I tend to dump the data source controls altogether because they don't give you the finer binding capabilities; they take away your ability to choose when and where to bind, something I don't personally like for performance reasons altogether.
ASP.NET MVC gives you a lot of options when you want to customize the way that ASP.NET MVC uses controllers. By default, ASP.NET uses a controller factory to handle MVC controller requests. A ControllerActionInvoker class, related to the controller, is solely responsible for invoking action method requests and returning the results. It is this class where the action method attributes are executed (the pre/post execution actions and the pre/post result actions). So both of these components are important classes.
In my applications, I like to customize both. It's easy to provide additional features for you to add on to. The options for implementing a custom controller factory are:
- Implement the IControllerFactory interface
- Inherit from DefaultControllerFactory, the base controller factory class
The later is usually the best option, unless you are completely rewriting the controller factory framework. By inheriting from this class, it makes it easy to add additional features. For instance, if you want to use a custom action invoker, you can do this in the GetControllerInstance method by doing:
public class MyCF : DefaultControllerFactory
{
private MyActionInvoker _inv = new MyActionInvoker();
protected override IController GetControllerInstance(Type controllerType)
{
var ctlr = base.GetControllerInstance(controllerType);
if (ctlr is Controller)
ctlr.ActionInvoker = _inv;
return ctlr;
}
}
We'll get to the action invoker later, but you can see GetControllerInstance opens it up for many things; for instance, you could use Unity or Castle to create a reference and assign any injected references into the controller itself, a popular topic lately because of MVC (although IOC/dependency injection has been a hot topic for a while, especially in the Java world, .NET seems to be a late adopter). This can happen here, so instead of using teh base class method (which does a reflective search for the specified type in all of the referenced projects, the logic could be changed to do:
var ctlr = this.LoadFromDIContainer(controllerType);
//rest of code
So you see, MVC opens your application up to many extensibility points, which is another place where the action invoker comes into play. The action invoker is responsible for invoking actions, of course. But an action can fail, either due do a threading abort exception (redirection), or because the action method couldn't be found. In any case, I like to wrap the action invoke with catch exceptions, instead of relying on HandleUnknownAction to do the work (which could also be another option by having all of your controller methods inherit from a common controller class, another extensibility point). Our action invoker could do:
public class ActInv : ControllerActionInvoker
{
protected override ActionResult InvokeAction(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary<string, object> parameters)
{
try
{
base.InvokeAction(controllerContext, actionDescriptor, parameters);
}
catch(ThreadAbortException aex)
{
//Log error specific to thread aborting
throw;
}
catch(Exception ex)
{
//Log error
throw
}
}
}
Here if an error occurs, logging occurs and the error is rethrown so the page fails. Here we could also return a redirection to the error page to show a friendly error, or use an exception logger attribute to handle the error details. Now, the key to this method is realizing this invokes on every action request. So we could do things like loading user information if they are logged in (the <forms loginUrl=""> still takes care of unauthenticated users). If the user information isn't cached, we could load and cache it, then use it to process the request. Any other code that you would run on every action execution can be put here too.
If you need to get more granular, you can override the InvokeActionMethod (executing the method itself; the result doesn't get returned directly here, but is stored internally) and InvokeActionResult (this will actually return the result of the action method). The latter method gives you direct access to the view or view result to do as you see fit. Since you have access to the view, and if you use a custom view, you can pass along any information to that view that you may need.
To use this controller factory, pass along a reference as shown below. This will replace the default with our new factory.
ControllerBuilder.Current.SetControllerFactory(new MyCF());
I hope I passed a long a few important tidbits about the MVC controller system, which is pretty powerful in its capabilities.
I must admit that Twitter is a subject that intrigues me, just like all of these social service media do. But this book is more than just about Twitter; it’s also about Twitter’s architecture and the use of REST-based applications and services that can be exposed through other means than just twitter (WCF, for example). It’s about making web requests and responses using HttpWebRequest and HttpWebResponse. It’s about Oath authentication requests which are utilized by Google and other services. So the concepts you will learn in this book go beyond twitter.
Content
The book is packed with a lot of content about the services Twitter offers. It’s clear that Daniel has a lot of knowledge on the subject. He packs the book with API references, code he’s written to simplify and make requests from Twitter, and other important information.
The book’s chapters are laid out relatively well. The chapters do flow in a relative order that works, moving from overview, to API references, to working with the raw data and the various API’s, and finally ending up with the advanced topics of performance, functionality, data push/pull, and cross platform applications.
I find a lot of value in the service references in the book. This makes a great reference to refer back to when using the Twitter service. The book also has a wonderful reference of error codes that twitter uses to return to the caller, as it isn’t straightforward to typical HTTP requests. The information on OAuth, as it is a pain to get setup correctly, is priceless too.
The book also covers the type of information (the properties within each object) that may be returned from a given object. Some of these properties change depending on the type of data being queried. For instance, date formats change depending on the API you are using, and so you have to be careful and handle this appropriately.
At the end, he also includes information about the custom API he wrote for Twitter (making Twitter more simple to use). His API is pretty fluent and easy to use, and has much online support (google TweetSharp for more information).
I think the book could use a few more .NET examples to reinforce the lessons learned. For instance, after all the API references, it would have been helpful to have another .NET code example of how to use one of the API methods, just to reinforce the chapter’s content.
Writing Style
Daniel is very knowledgeable about the subject, and you can tell from his writing. One of his strengths is his ability to lay out a solution to the challenges of Twitter. If you don’t like to work with the low-level details in Twitter, you may have a hard time following the book; that is the kind of book this is, after all, because that is simply how Twitter works.
I feel that some times, the book tells you how to solve a problem, and not properly explain what the problem is. This isn’t always the case, but certain areas of the book left me wondering why, instead of just getting code to resolve the problem.
Conclusion
Great book, worth the read, but know what you are getting into. This book gets into the detailed aspects you need to be aware of, which is those low-level error code, OAuth authentication, web requests and processing XML/JSON data, etc.
ASP.NET MVC is a wonderful thing. One of the many great features is the ability to customize all of the .NET framework's code by swapping out one implementation and using another. One such instance is creating a custom view engine, which you can do as illustrated in this example: http://www.singingeels.com/Articles/Creating_a_Custom_View_Engine_in_ASPNET_MVC.aspx. The point of my article is not to illustrate how this can be done, but about how to customize it for your needs. By default, the web forms view engine looks for views in the folder of the controller or the shared folder. So if you try to trigger an action method "Index" within the controller of type CustomerController, a partial view (.ascx) or the view (.aspx) is sought for in the ~/Shared folder or ~/Customer folder.
Now, I tend to like to use partial views in order to separate and reuse functionality a lot. So I tend to have a lot of partial views that tend to get reused across pages and I don't want everything to be in the shared folder (by default, partial views have to be in the shared folder or in the same folder as the controller). So I added some code to the view engine that allowed me to create subfolders within the shared folder and for the view engine to look for the classes there. Imagine this folder structure:
Shared
Customers
Orders
Products
So the shared folder breaks up my partial views into the folder above.
Thinking long-term, rather than hard-coding all these folder references and assigning them to the ViewLocationFormats and PartialViewLocationFormats properties, I wanted something that I wouldn't have to worry about changing later. So in true ASP.NET MVC framework form, I created some extra code to create the ability to automatically add references to subfolders too. In order to do this, it's required to use the VirtualPathProvider class to extract the URL, as in the following code:
public MyViewEngine() {
var locations = new List<string>
{
"~/Views/{1}/{0}.aspx",
"~/Views/{1}/{0}.ascx",
"~/Views/Shared/{0}.aspx",
"~/Views/Shared/{0}.ascx"
};
var dir = this.VirtualPathProvider.GetDirectory("~/Views/Shared");
var subs = dir.Directories.OfType<VirtualDirectory>();
foreach (var sub in subs)
{
locations.Add("~" + sub.VirtualPath.Substring(sub.VirtualPath.IndexOf("/", 2)) + "{0}.ascx");
}
base.ViewLocationFormats = locations.ToArray();
base.PartialViewLocationFormats = base.ViewLocationFormats;
}
This is the constructor for the custom view engine. It contains some additional code to use the VirtualPathProvider property (a property of our custom view engine) to extract the subdirectories of the shared folder. You see the four hard-coded references at the beginning, and so we need to create virtual path strings (which start with "~" and work from the beginning of the virtual directory) to add to the custom list. When working with folders using VirtualPathProvider, the issue becomes the way paths are referenced. By default, the path may be:
/MyVirtualFolder/Views/Shared/Customers/
When you need:
~/Views/Shared/Customers/
And so some additional work to format the path is needed (the substring strips off the virtual directory folder. Now we have a component that will allow the MVC framework to look for partial views in all subdirectories in the shared folder.
The latest Telerik MVC set of components features a ScriptRegistrar component that's responsible for compressing or combining scripts into a single file. This compression utility is very easy to implement: to setup this component, use the following steps:
1. In your configuration file, add the following line to the httpHandlers element in <system.web> and <system.webserver>:
<add verb="GET,HEAD" path="asset.axd" validate="false" type="Telerik.Web.Mvc.WebAssetHttpHandler, Telerik.Web.Mvc"/>
2. Use the ScriptRegistrar and groups to group scripts together. Preferrably, put this in the master page at the very end of the page before the ending </body> tag.
<% Html.Telerik().ScriptRegistrar().Scripts((s) =>
{
s.AddGroup("MyGroup", (g) =>
{
g.Add("script1.js").Add("script2.js").Add("script3.js");
}
}).Render(); %>
Now we have our scripts defined, but if you run the app, you will be disappointed by finding out three script files were added. Instead, we need to add some additional properties to the group definition.
s.AddGroup("MyGroup", (g) =>
{
g.Add("script1.js").Add("script2.js").Add("script3.js").Combined(true).Compress(true).CacheDurationInDays(10);
}
The Combined() method signals to combine all three scripts together within this group The Compress() method signals to compress the scripts, and the CacheDurationInDays method specifies the number of days to cache the scripts.
This can also be performed by stylesheets, without the ability to combine and compress them. You can group them together using the same approach, except using the StyleSheets method.
This setup produces the following output.
<script type="text/javascript" src="/asset.axd?id=mwAAAB-LCAAAAAAABADtvQdgHEmWJSYvbcp7f0r1StfgdKEIgGATJNiQQBDswYjN5pLsHWlHIymrKoHKZVZlXWYWQMztnbz33nvvvffee--997o7nU4n99__P1xmZAFs9s5K2smeIYCqyB8_fnwfPyJ-8UfT9qNHH2WrVVlMs7aolnffbf90dpk107pYtR-NPrqkr_d2dh6O7413d3fujXfos-lHj9p6ndMvs48e3fv0_ugj-vm9X_zRitqeVMs2X7Z3XzOAhlqf83fVR492Rh8tqcVFXa1Xu-Ofbj76JSP-fNf7fI8___4v-f4v-X8AJmOKf5sAAAA%3d"></script>
<link type="text/css" href="/asset.axd?id=kwAAAB-LCAAAAAAABADtvQdgHEmWJSYvbcp7f0r1StfgdKEIgGATJNiQQBDswYjN5pLsHWlHIymrKoHKZVZlXWYWQMztnbz33nvvvffee--997o7nU4n99__P1xmZAFs9s5K2smeIYCqyB8_fnwfPyJ-8UfT9qNHH7X5u_butGk-Gn10SX_u7ew8HN8b7-7u3Bvv0GfTjx619TqnX2YfPbr36f3RR_Tze7_4oxW1PamWbb5s757w2-f8efXRo53RR0v69nXR5mMA_iUj_nhXPm7zMq-Lt-Pq_LyY5tTdA2n0_V_y_V_y_wCso4bJkwAAAA%3d%3d" rel="stylesheet"/>
The other option for adding scripts is to use the DefaultGroup method, a method that uses the default group to setup scripts for. For instance, we setup a custom group, but if you only need one group, we can use the DefaultGroup method to define all our scripts in.
I've spent some time figuring out how to bridge the gap between web forms and ASP.NET MVC style of development. Just because the UI works differently, doesn't mean the actual framework works in a different way. If you use .NET 3.5 SP 1 for both your web forms and MVC style development, it is helpful to come up with a helper component to serve up the context. Why would I suggest this? Well, in web forms, you can access the current context information by accessing System.Web.HttpContext.Current, which returns the current HttpContext being executed. The HttpContext object has an array of services (request, response, etc.) that you can make use of. This is available in ASP.NET MVC in the controller too, via the ControllerContext.HttpContext reference.
The difference between the two is that the former uses an HttpContext object, while MVC uses an object of type HttpContextBase in System.Web.Abstractions.DLL. The context is a reference to HttpContextWrapper, which inherits from HttpContextBase, and provides you with all of the services previously mentioned. So basically, you are working with the same thing, but not the same object. But if you use 3.5 for all of your development, you can use the same object to leverage both, by creating a helper class and always referring to this for your context.
public static class HttpWebContext
{
public static HttpContextBase GetContext()
{
return new HttpContextWrapper(HttpContext.Current);
}
}
This works in web forms because this is how it works anyway, while MVC uses this in its underlying architecture (if you use a tool like Reflector you can dig down into the code to find it). And so this common component shares the context across two environments, and its isolated and follows the Singular Repsonsibility Principle [SRP]. Now what about testability, because your internal components will be using this, and the http context won't be available in a testing environment (since it's web framework specific). For instance, your controller may do something like:
public ActionResult View()
{
var context = HttpWebContext.GetContext();
//use the context in some way
return View();
}
So how can that type of method be mocked? If you use TypeMock, this can be done easily:
var ctx = Isolate.Fake.Instance<HttpContextBase>();
var requestFake = Isolate.Fake.Instance<HttpRequestFake>();
Isolate.WhenCalled(() => ctx.Request).WillReturn(requestFake);
//Additional faking here
Isolate.WhenCalled(() => HttpWebContext.GetContext()).WillReturn(ctx);
For Moq, this is harder because it doesn't mock statics; so you could make it an instance-based approach, or you could use a provider approach. For instance, create a provider that has:
public abstract class ContextProvider
{
public HttpContextBase GetContext();
}
Have two implementations, one for returning the current context like we have above, and have another returning a faked http context that inherits from HttpContextBase, and then store this reference in the configuration file or pass it in as a parameter to a class. You could get kind of crazy with it, but by using the provider approach, it helps you differentiate the web environment and test environment without exceptions occurring.
Would this approach work in .NET 2.0? Well, the great feature about 3.5 is the System.Web.Abstractions, which contains the HttpContextBase class that handles this for you. So if you can use 3.5, you can leverage this API for your needs. Otherwise, you would have to create your own wrapper, which is possible but tedious (since it's such a big class).
This is a continuation of a blog series on creating services. You can find the previous articles here:
So the ApplicationContext object uses a service loader as one way to load the IService objects into it. This class exists solely to load these services into the context. This object is then linked into the Application context through the configuration file. The below example is used for loading MVC services by default (you can inherit, override this method, and add additional ones you use as a way to make it easier for loading the services you need). This object already exists in the Nucleo.Web.Mvc DLL, in the Nucleo.Web.Context namespace.
public class MvcApplicationContextServiceLoader : IApplicationContextServiceLoader
{
#region " Methods "
public virtual void LoadServices(IApplicationContextProvider provider)
{
provider.RegisterService<IApplicationStateService>(new MvcApplicationStateService());
provider.RegisterService<IBrowserCapabilitiesService>(new WebFormsBrowserCapabilitiesService());
provider.RegisterService<ICookieService>(new MvcCookieService());
provider.RegisterService<INavigationService>(new MvcNavigationService());
provider.RegisterService<IPostDataService>(new MvcPostDataService());
provider.RegisterService<ISessionStateService>(new MvcSessionStateService());
provider.RegisterService<IServerUtilityService>(new MvcServerUtilityService());
provider.RegisterService<IUrlResolutionService>(new MvcUrlResolutionService());
}
#endregion
}
The LoadServices method is where the action happens. The application context provider is used to receive these services and supply them to the ApplicationContext. You don't actually have to worry about that; the service provider is used by the context to serve up these services. This class is then linked up in the configuration file. See the following example for the setup:
<configSections>
<nucleo>
<section name="contextSettings" type="Nucleo.Context.Configuration.ContextSettingsSection,Nucleo" />
</nucleo>
</configSections>
<nucleo>
<contextSettings contextLoaderType="Nucleo.SampleClasses.Context.SampleApplicationLoader,Nucleo.OnlineTests" />
</nucleo>
The context settings section is the configuration object for specifying the loader you would like to use. At runtime, the ApplicationContext object uses this to load the relevant services, so when you do:
context.GetService<ICookieService>();
A valid service will be returned to you. We'll talk more later about the purpose of the context provider later, how that's configured .
I've been working on a new MVC project and man has it been enlightening! It's my first MVC project, so I get to go through all the things I thought I knew from reading Pro ASP.NET MVC Framework (Apress by Steve Sanderson) to realizing I don't know squat,and have to really delve into the learning in order to finish the project, a task which I knew I was getting into and greatly accept the challenge. Anyway, as I've been developing, I've been trying to use Moq to create my unit tests. It's a free mocking library that enables you to write code that mocks your existing objects. While most libraries heavily use interfaces for writing mocks, Moq can mock classes that have the methods or properties to override marked as virtual (and there are some other conditions as well; you can see an example on Stephen Walther's blog). As you can see, Moq is great and is useful for MVC applications, and can be used in web forms in a more limited fashion.
TypeMock, however, offers you a few more conveniences over mocking. For instance, Moq doesn't support mocking static methods, internal methods, and a few other scenarios. In fact, Moq is a good approach if you design software using the DI pattern, as is illustrated below:
public class TestClass
{
public TestClass(IDependency dep) { }
}
This is where a dependency is passed in to the constructor (or it can be via a property), which Moq can setup easily as in the following code:
var depFake = new Mock<IDependency>();
//Setup any mocking here
var tc = new TestClas(depFake.Object); //fake gets inserted here
// tc.Dep = depFake.Object; <-- this is an alternative approach
However, TypeMock allows you to use other approaches as well, which fits closer to my development style. For instance, suppose you have this type of class that uses the dependency:
public class TestClass
{
private TestClass() { }
public static TestClass Create()
{
var c = new TestClass();
c.Dep = DepResolver.Get();
return c;
}
}
With Moq, we have no inherent way to tap into this method. This is where TypeMock comes in. TypeMock allows us to tap into this method a couple of ways. First, we could skip the Create method altoghether using:
var tc = Isolate.Fake.Instance<TestClass>();
Isolate.WhenCalled(() => TestClass.Create()).WillReturn(tc);
The first line creates our fake, similar to Moq's "new Mock<TestClass>" syntax. Rather than returning a proxy, it returns an actual instance of our mocked class. The second statement provides a way to override the static method and return directly our fake. This may not be as useful, so let's look at the next way to tap into this method:
var dep = Isolate.Fake.Instance<IDependency>();
Isolate.WhenCalled(() => DepResolver.Get()).WillReturn(dep);
var tc = TestClass.Create();
When this code runs, the TestClass instance is actually created, and that code works as is. But the code revolving around the IDependency is faked, so that the DepResolver returns our fake and doesn't actually run. So you can see some of the ways that TypeMock allows developers to tap into their code without forcing a design. We'll look at other ways this can happen later on.
Note: This doesn't mean Moq is bad by any means; designing your software for testability is a good thing, as it's good to leverage unit tests to ensure accuracy of your code doing what it was supposed to do. It's just that TypeMock gives you a few other options, and this is one of the additional features that TypeMock provides.
My latest release at http://www.codeplex/nucleo also features a new Link control (in the Nucleo.Web.Controls namespace). This control tries to integrate two kinds of links; clickable links which fire an event, and redirection links that navigate to another site. The link control incorporates an enumeration to incorporate this: the ClickAction property of type LinkClickAction. When set to FIreEvent, the client-side clicked event or server-side clicked event (depending on rendering mode set by the RenderMode property) of the control, whereas Redirect fires a Redirecting event.
The redirecting parameters can be set by establishing the NavigateUrl property. This property specifies the location to redirect to. Another option, Target, specifies whether to use a new window to open the link in, or the same window. The link also specifies a NavigateUrlFormatString that you can use to do something like this:
<n:Link ... NavigateUrl='<%# Eval("Key") %>' NavigateUrlFormatString="products.aspx?id={0}" />
When a format string is specified, the navigateurl property is injected in the format string, as a convenience option. Only one format placeholder is available. The server component also has helper methods to get the final values for text (which has Text and TextFormat properties), navigate url, and more. The GetText, GetNavigateUrl, and GetTarget methods are convenience methods for extracting this information as the control would need for rendering.
These options can be changed on the client-side; each of the main properties (navigateUrl, clickAction, target, text, etc.) is available on the client except for the format strings. So you can change the way the link reacts to clicks, change where it navigates to, and more.
var link = $find("<%= l1.ClientID %>");
link.set_text("New Text");
link.set_clickAction(Nucleo.Web.Controls.LinkClickAction.Redirect);
link.set_navigateUrl("http://www.yahoo.com");
link.refreshUI();
Note the refreshUI method; this is a method that's used to perform the actual updates. This is important because the UI changes won't occur until that method calls. The reason is because I created a batch method to perform these updates for performance reasons (updating on every setter would be cumbersome).
If you've used MVC, you know the System.Web.Abstractions API offers you a lot of capabilities to make it easy to write unit tests in your MVC controllers. It's really easy to setup a Moq or TypeMock unit test to create a fake implementation of objects like HttpContextBase. Some objects are not as testable. For instance, UrlHelper may not be as easy to implement testing with (although TypeMock can test pretty much any object very easily since it doesn't require a DI setup or interfaces). Rather than leverage this approach, I chose an approach not just limited to web forms, and something that may be available in a windows, silverlight, or WPF environment as well. Welcome the ApplicationContext object and the IService interface.
ApplicationContext is a central object that is used to make services available to those who need it. You have to go through a process of loading these services; however, this process isn't that hard (will cover in another blog post). To use the application context looks something like:
ApplicationContext context = ApplicationContext.GetCurrent();
ILoggerService service = context.GetService<ILoggerService>();
Every service that the application context uses implements IService (this interface doesn't really do anything, but simply is used as a marker). ILoggerService happens to be one of the services available (ILoggerService implements IService) and so it's retrievable vai the ApplicationContext object. Built into the framework is the NucleoContext namespace (which contains environment-agnostic services) and Nucleo.Web.Context (web/MVC specific services) that you can use the ApplicationContext object to retrieve.
The idea of this object is to make available core services. For instance, in MVC, you can instantiate the service you need (HttpContextWrapper, HttpRequestWrapper, etc.). Instead of using this, you can use the application context to request these services instead. I don't have all of the existing web services created; however, I do have services available for cookies, querystring, forms, and more. Rather than create one big request object, I instead break up each of these into smaller services by function.
How do you retrieve? That's the purpose of the service loader, a subject we'll discuss next. You can get the latest code base for this example from: http://www.codeplex.com/nucleo
I've been working on a project available at for http://www.codeplex.com/nucleo. It's a project I've had in the works for a while, and it's finally coming to fruition. So I am starting to create blog posts explaining features about these controls. I am really excited about this button because I think it offers you more than what other control vendors offer you (at least the ones I seen, because I don't know every control suite out there). Anyway, my button comes with some nice features.
First, it has a DisableUntilPageLoad property that will disable the button until page load scripts have run. This is a useful feature I found in Professional ASP.NET AJAX from Wrox that really does make sense. So I added it into my button control, which simply can be enabled via:
<n:Button ... DisableUntilPageLoad="True" />
And now the button doesn't enable until page loads on the client. Note: It's up to you to ensure JavaScript works :-; Next, we have the ability to disable the button when it clicks by setting the DisableOnFirstClick property to true. This disables the button permanently, but can be re-enabled using the enabled client-side property. The DisableOnFirstClickTimeout specifies a timeout in seconds, which will be used to re-enable a button. This is a nice feature because often developers want to prevent double-clicks from happening, yet still ensure that they can click the button. Using these setting:
<n:Button DisableOnFirstClick="True" DisableOnFirstClickTimeout="300" />
This disables the button on click, then re-enables it at 300 milliseconds. The button does support all the traditional IButtonControl implementations, but doesn't use the ASP.NET implementation; rather, I use a cleaner approach that can be used on both the server and the client.
The button also specifies a mode to render in, whether link button, push button, or image button. This mode is then rendered appropriately. This then requires only one button instance, and can be changed on the server. It currently cannot be changed on the client, but should be something I implement in the future.
This are some of the Button control's available offerings. More to come soon on some of the other controls.
Rating: 5 out of 5
I believe Pro ASP.NET MVC Framework is one of the best books on the market about MVC. This book is crammed with a lot of information that you need to know as a developer. While he doesn't cover each subject fully (no book really does that), he does cover the major topic points related to MVC in-depth, and touches upon the other concerts that you need to be aware of to implement or customize MVC for your own purposes. I’ve broken up my review into several major subsections related to the book and analyze each one individually. From an overall level, I think the book really did well in its explanation and examples of MVC.
Book's Knowledge
This book is really crammed with lots of valuable information. I find myself referring back to the book when working with MVC, because it has a lot of various important sections about how to use JQuery to dynamically change MVC partial views within a view, how to customize the creation of a controller, and other important facts. There is so many small or medium details regarding the MVC framework that is important to know about covered in this book, that it does really make it a very beneficial book.
The chapters on each major feature (views, routing, controllers, etc.) are very long, which is great because they contain so much information about each of the subjects. I was really impressed with the information packed into each of these chapters. After reading the book, I felt comfortable enough to work on MVC and understand some of the concerns when implementing MVC for my own applications. I felt there was minimal downtime trying to play with MVC to understand its inner-workings; I really felt confortable jumping in.
Writing Style
I really like Steven's ability to clearly articulate points about MVC. If the writer is not fluent, I tend to lose interest, but I didn't lose interest at all in this book. This book doesn't just talk about the functionality, but actually illustrates its use through examples and theory, which is important for such a big subject. That's not to say he doesn't explain his code, which he does in the right amount of detail.
Content Structure
Though a pro book, the author ensures that he covers the basic prerequisites for the book, to fill in the user how MVC works. The book continues on with three chapters of a sample MVC application, explaining it some as he goes, following up with most of the book detailing each features.
The main complaint of the book that I have is that Chapters 4, 5, and 6 cover the basics of creating an MVC sports store application and tries to get you familiar with MVC by jumping right in without a lot of preliminary discussion. While he does discuss what he’s illustrating, I feel it would have been helpful to cover the documentation of the features first, and then rolled through the example last, with a bigger/more complex example.
The plus to this design is that the sample walks you through the basics, and the subsequent materials enhance your understanding of routing, views, controllers and actions, data entry and model binding, AJAX and client-scripting, and security.
I found much use alone out of the chapters on using AJAX to use an unobtrusive JavaScript approach and the concerns to have with implementing security (since ASP.NET web forms handled certain security features for you automatically and MVC does not).
Implementation
While I do have a deep technical background, the concept of MVC is somewhat foreign to me; I had a familiarity to the pattern, but didn't know anything about the product. After reading this book, I felt very confident about my ability to create an MVC site. There were some curveballs and I had to reference the book again and again, but I felt overall that this book was a fantastic resource to get me going. It's the only book I read on the subject (outside of the NerdDinner resource provided by Scott Guthrie).
Conclusion
MVC is a great product. While in its infancy (2.0 has some great features coming), MVC gives you control over the UI that web forms took away. MVC is a big undertaking and does require some knowledge about how it works. I believe this book is a great way to take a big chunk out of the mystery of MVC, especially for those coming from a web forms world.
I'm starting to get into a project using ADO.NET entity model. This is a pretty cool technology, and I like a lot of the features (especially the logical model approach). There are some things I really dislike about Phase 1, like having to delete the entire model or edit SSDL manually (or with XML tool) - anybody know of some free tools available for this? But overall, I like the approach, and the concept, so I look forward to adding features.
Some features I want to add is automatic logging. Sometimes, you just need to know what's going on with your application to see if the logic is working correctly. I often create a logger class, create an ILogger interface with a LogError and LogMessage methods, and create derived classes to log to event log, console, health monitoring, etc. That is out of scope for this article, but I want to focus on the idea of extensibility. I've been reading articles about how to plugin to the provider architecture and other approaches, but I don't personally want to affect the architecture. Rather, I'd rather take the wrapping approach. This is separated and isolated from any provider architecture changes over the years. While that's not a major concern anyway (at least for me), a separate class seems like a good approach.
So I use a class that does something like this:
public class ObjectContextHelpers
{
public static void SaveNewObject(CustomObjectContext context, string entitySetName, object entity)
{
//get a reference to the logger - pass in as ref or via singleton, or some other approach
logger.LogMessage("Attempting to save object for entity set " + entitySetName);
//Can log other details, number of objects commiting, details about object state entries, and other information
try
{
context.AddObject(entitySetName, entity);
}
catch(Exception ex) { logger.LogMessage("Saving object failed: " + ex.ToString()); }
logger.LogMessage("Saved object for entity set " + entitySetName);
}
public static CustomObjectContext Create()
{
return new CustomObjectContext(ConfigurationManager.ConnectionStrings["ConnString"].ConnectionString);
}
}
Here we have a Create method that uses one common connection string, which is a connection string pre-configured (assuming that you aren't building a custom library that may require configurability).
More Posts
Next page »