Internet Explorer 9 is finally here...well almost. Microsoft is releasing their new browser on March 14, 2011.
IE9 has a number of improvements, including:
-
Faster, Faster, Faster. Did I mention it is faster? With the new browsers coming out from Mozilla, Google, and Microsoft, there have been a flood of speed test coverage. Chrome has long held the javascript speed crown. But according to
Steven J. Vaughan-Nichols over at ZDNET..."for the moment at least IE9 is actually the
fastest browser I’ve tested to date." He came to this revelation after figuring out that the 32-bit version of IE9 has the new
Chakra JIT (the 64-bit version doesn't). It also has a DirectX-based rendering engine so it can do
cool tricks once reserved for desktop applications.
-
Windows 7 Desktop Integration. Read
my post for more details. Unfortantely, they didn't integrate
my ideas...at least not yet :)
-
Hot new UI. Ok, they "borrowed" some ideas from Chrome...but that is the best form of flattery.
-
Standards Compliance. A real focus on HTML5 and CSS3. Definite goodness for developers.
So, go get yourself some IE9 on Monday and enjoy!
Microsoft has been beta testing SP1 since December of last year. Today, it was released to MSDN subscribers and will be available for public download on March 10, 2011.
The service pack includes a slew of fixes, and a number of new features:
- Silverlight 4 support
- Basic Unit Testing support for the .NET Framework 3.5
- Performance Wizard for Silverlight
- IntelliTrace for 64-bit and SharePoint
- IIS Express support
- SQL CE 4 support
- Razor support
- HTML5 and CSS3 support (IntelliSense and validation)
- WCF RIA Services V1 SP1 included
- Visual Basic Runtime embedding
- ALM Improvements
Of all the improvements, IIS Express probably has the largest impact on web developer productivity.
According to Scott Gu, it provides the following:
- It’s lightweight and easy to install (less than 10Mb download and a super quick install)
- It does not require an administrator account to run/debug applications from Visual Studio
- It enables a full web-server feature set – including SSL, URL Rewrite, Media Support, and all other IIS 7.x modules
- It supports and enables the same extensibility model and web.config file settings that IIS 7.x support
- It
can be installed side-by-side with the full IIS web server as well as
the ASP.NET Development Server (they do not conflict at all)
- It works on Windows XP and higher operating systems – giving you a full IIS 7.x developer feature-set on all OS platforms
IIS Express (like the ASP.NET Development Server) can be quickly launched to run a site from a directory on disk. It does not require any registration/configuration steps. This makes it really easy to launch and run for development scenarios.
Good stuff indeed. This will make our lives much easier. Thanks Microsoft...we're feeling the love!
There are a few different APIs for accessing Twitter from .NET. In this example, I'll use linq2twitter. Other APIs can be found on Twitter's development site.
First off, we'll use the LINQ provider to pull in the recent tweets.
1: public static Status[] GetLatestTweets(string screenName, int numTweets)
2: {
3: try
4: {
5: var twitterCtx = new LinqToTwitter.TwitterContext();
6: var list = from tweet in twitterCtx.Status
7: where tweet.Type == StatusType.User &&
8: tweet.ScreenName == screenName
9: orderby tweet.CreatedAt descending
10: select tweet;
11: // using Take() on array because it was failing against the provider
12: var recentTweets = list.ToArray().Take(numTweets).ToArray();
13: return recentTweets;
14: }
15: catch
16: {
17: return new Status[0];
18: }
19: }
Once they have been retrieved, they would be placed inside an MVC model.
Next, the tweets need to be formatted for display. I've defined an extension method to aid with date formatting:
1: public static class DateTimeExtension
2: {
3: public static string ToAgo(this DateTime date2)
4: {
5: DateTime date1 = DateTime.Now;
6: if (DateTime.Compare(date1, date2) >= 0)
7: {
8: TimeSpan ts = date1.Subtract(date2);
9: if (ts.TotalDays >= 1)
10: return string.Format("{0} days", (int)ts.TotalDays);
11: else if (ts.Hours > 2)
12: return string.Format("{0} hours", ts.Hours);
13: else if (ts.Hours > 0)
14: return string.Format("{0} hours, {1} minutes",
15: ts.Hours, ts.Minutes);
16: else if (ts.Minutes > 5)
17: return string.Format("{0} minutes", ts.Minutes);
18: else if (ts.Minutes > 0)
19: return string.Format("{0} mintutes, {1} seconds",
20: ts.Minutes, ts.Seconds);
21: else
22: return string.Format("{0} seconds", ts.Seconds);
23: }
24: else
25: return "Not valid";
26: }
27: }
Finally, here is the piece of the view used to render the tweets.
1: <ul class="tweets">
2: <%
3: foreach (var tweet in Model.Tweets)
4: {
5: %>
6: <li class="tweets">
7: <span class="tweetTime"><%=tweet.CreatedAt.ToAgo() %> ago</span>:
8: <%=tweet.Text%>
9: </li>
10: <%} %>
11: </ul>
Microsoft launched a
website dedicated to the demise of IE6. Here's their pitch...
10 years ago a browser was born. Its name was Internet Explorer 6. Now that we’re in 2011, in an era of modern web
standards,
it’s time to say goodbye. We'll watch Internet Explorer 6 usage drop to
less than
1% worldwide, so more websites can choose to drop support for Internet Explorer 6, saving hours of work for web developers.
Thanks Microsoft! We've been waiting for this day to come for a long time. Of course, it would have been nice if IE6 was gone 5 years ago...but who's counting.
An interface defines a contract to be implemented by one or more classes. One of the keys to a well-designed interface is defining a very specific range of
functionality. The profile of the interface should be limited to a single purpose & should have the minimum methods required to implement this functionality. Keeping the interface tight will keep those implementing the interface from getting lazy & not implementing it properly. I've seen too many overly broad interfaces that aren't fully implemented by developers. Instead, they just throw a NotImplementedException for the method they didn't implement.
One way to help with this issue, is by using extension methods to move overloaded method definitions outside of the interface.
Consider the following example:
1: public interface IFileTransfer
2: {
3: void SendFile(Stream stream, Uri destination);
4: }
5:
6: public static class IFileTransferExtension
7: {
8: public static void SendFile(this IFileTransfer transfer,
9: string Filename, Uri destination)
10: {
11: using (var fs = File.OpenRead(Filename))
12: {
13: transfer.SendFile(fs, destination);
14: }
15: }
16: }
17:
18: public static class TestIFileTransfer
19: {
20: static void Main()
21: {
22: IFileTransfer transfer = new FTPFileTransfer("user", "pass");
23: transfer.SendFile(filename, new Uri("ftp://ftp.test.com"));
24: }
25: }
In this example, you may have a number of overloads that uses different mechanisms for specifying the source file. The great part is, you don't need to implement these methods on each of your derived classes. This gives you a better interface and better code reuse.
Google has a great cloud-based calendar service that is part of their Gmail product. Besides using it as a personal calendar, you can use it to store events for display on your web site. The calendar is accessible through Google's GData API for which they provide a C# SDK.
Here's some code to retrieve the upcoming entries from the calendar:
1: public class CalendarEvent
2: {
3: public string Title { get; set; }
4: public DateTime StartTime { get; set; }
5: }
6:
7: public class CalendarHelper
8: {
9: public static CalendarEvent[] GetUpcomingCalendarEvents
10: (int numberofEvents)
11: {
12: CalendarService service = new CalendarService("youraccount");
13: EventQuery query = new EventQuery();
14: query.Uri = new Uri(
15: "http://www.google.com/calendar/feeds/userid/public/full");
16: query.FutureEvents = true;
17: query.SingleEvents = true;
18: query.SortOrder = CalendarSortOrder.ascending;
19: query.NumberToRetrieve = numberofEvents;
20: query.ExtraParameters = "orderby=starttime";
21: var events = service.Query(query);
22: return (from e in events.Entries select new CalendarEvent()
23: { StartTime=(e as EventEntry).Times[0].StartTime,
24: Title = e.Title.Text }).ToArray();
25: }
26: }
There are a few special "tricks" to make this work:
- "SingleEvents" flag will flatten out reoccurring events
- "FutureEvents", "SortOrder", and the "orderby" parameters will get the upcoming events.
- "NumberToRetrieve" will limit the amount coming back
I then using Linq to Objects to put the results into my own DTO for use by my model. It is always a good idea to place data into your own DTO for use within your MVC model. This protects the rest of your code from changes to the underlying calendar source or API.