Windows Phone 7 Developer Launch

by michael 10/1/2010 9:29:14 AM

The image below links to local MSDN WP7 training events.

wp7_signature_banner_lg

Yes, this post is a shameless attempt to win a free phone.  I really did want to attend one of these training sessions, but I have already missed the Little Rock and Tulsa events.  I think there is supposed to be an online MSDN Simulcast on October 12, so I will probably wait for that.

Currently rated 3.1 by 33 people

  • Currently 3.060606/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:

ASP.NET MVC from Basics to Tips and Tricks

by michael 11/16/2009 5:41:00 PM

I had a great time speaking at the Fort Smith .NET User Group last week.  ASP.NET MVC is a subject that I am very passionate about.  I recently had the pleasure of developing an e-commerce website for Wolff Wire – Office Organizers using this technology.  Since then I have been using it anytime I can.  The development feels so much cleaner, and the code is more organized than in ASP.NET WebForms.  In addition the HTML output is not cluttered with ViewState and ClientIDs.

Unfortunately I wasn’t able to get quite as far as I wanted with the presentation, so I figured that I would go ahead and hit the highlights of my presentation in this blog post.

I am not an expert, so if anyone has better ways of doing things please let me know.

The Basics

First off MVC stands for Model-View-Controller.  Below some of the basic components are listed.

  • Model = Data / State
  • View = Responsible only for rendering the HTML output (.aspx page)
  • Controller = Presentation Logic (class with action methods)
    • HTTP operations are routed here
    • Responsible for selecting the appropriate View
    • Provides the View with the proper Model
  • Routing = URL Processing Engine
    • Determines based on the URL what Action Methods to call on the Controller
    • Default URL Structure = Controller Prefix/Action/ID = ex. Product/Detail/2
    • Very Customizable
  • Html Helpers = Methods that generate html (used in View)
    • Partially equates to WebForms Controls
    • Encapsulates more advanced rendering logic outside of the View
    • Html.ActionLink is very important
      • ex. Html.ActionLink( DisplayText, Action, Controller, new {ID or other defined value as property of an anonymous type}, new {anchor tag html attribute defined as a property of an anonymous type})

 

Tips and Tricks / Best Practices

  1. Use Html.ActionLink 
    Do not manually create anchor tags, because if the routing configuration is changed your links will be broken.  Html.ActionLink automatically renders appropriate URLs based on the current routing configuration.
  2. Use Descriptive Keyword Rich Names Instead of Database Table IDs (SEO) In URLs
    This is particularly useful for public facing websites such as blogs or e-commerce sites.  Google and other search engines index keywords in URLs, and ID numbers yield no benefit.  Again the default URL structure in ASP.NET MVC is “Controller Prefix/Action/ID” (Product/Detail/2).  There is nothing stating that “ID” has to be an integer.  You could have something like “Product/Detail/paper-tray”.  Just be sure that the controller action methods “ID” parameter is typed as a string.  I generally keep an indexed column in my database for this.  It is a lower case variation of the display name with dashes in place of spaces.  I suppose you could also use a lookup dictionary that maps to the table ID instead.
  3. Configure Routing to Optimize URLs
    Don’t feel bound to the default URL routing configuration.  The routing is very customizable as seen below.
    routes.MapRouteLowercase(
        "Catalog",                                             
        "workspace-organizers",                          
        new { controller = "Category", action = "Index" } 
    );
    //ex. /workspace-organizers
    
    routes.MapRouteLowercase(
        "ProductCategory",                                             
        "{urlname}/cat",                          
        new { controller = "Product", action = "Index", urlname = "" } 
    );
    //ex. /desktop-accessories/cat
    
    routes.MapRouteLowercase(
        "ProductDetail",                                              
        "{urlname}/prod",                         
        new { controller = "Product", action = "Details", urlname = "" }  
    );
    //ex. /cd-holder/prod
  4. Use Strongly Typed Models
    Avoid using hard coded “Magic” strings whenever possible.  One way to send model data to the view is through the use of the ViewData dictionary object.
    public ActionResult Index()
    {
        ViewData["Message"] = "Welcome to ASP.NET MVC!";
        return View();
    }
    <h2><%=
    Html.Encode(ViewData["Message"]) 
    %></h2>
    This is problematic for a number of reasons.  Errors from typos and broken references when refactoring may not show up until runtime.  Also complex objects stored in the dictionary will have to be typed in the view in order to access their properties.  It is best to give your view a specified model type as shown below.
    public ActionResult Index()
    {
        string strMessage = "Welcome to ASP.NET MVC!";
        return View(strMessage);
    }
    Next in the view give the page declaration’s inherits attribute a type.
    Inherits="System.Web.Mvc.ViewPage<string>"
    Then you can utilize the “Model”, which is the instance of the specified type.
    <h2><%=
    Html.Encode(Model) 
    %></h2>

  5. Use ViewModels 
    Often it is necessary to have more than one type represented as model data.  I prefer to have a model per view that consolidates all the required types.
    public class ProductIndexViewModel : ViewModelBase
    {
        public string CategoryName { get; set; }
        public IEnumerable<CatalogListItem> CatalogItems { get; set; }
    }
    public ActionResult Index(string id)
    {
        var viewmodel = new Models.ProductIndexViewModel();
        viewmodel.CatalogItems = productRepository.GetCatalogItems(id);
        viewmodel.CategoryName = categoryRepository.GetCategoryName(id);
        return View(viewmodel);
    }
  6. Use a Master ViewModel
    How do you get data to a master page so it can be used across multiple pages?  A shopping cart summary is one example of where this is needed.

    One option is to have a master controller that all relevant controllers would inherit.  The master controller could set a value in the ViewData dictionary.  Again I don’t like this because it isn’t strongly typed.

    Another option is to use RenderAction to simulate an http request and return a partial view rendered to html.  This has some advantages in that sections of a page can be cached.

    The technique I like to use is to create a master viewmodel that the other models inherit.  Master pages can have a specified model type just like normal views, so I set the master page’s type to the view model base.  This will work as long as every view that implements the master page receives a viewmodel that inherits from the master view model.
    public class ViewModelBase
    {
        public ViewModelBase()
        {
            SiteHeaderText = "MVC Outdoor Catalog";
        }
    
        public string SiteHeaderText { get; set; }
    }
    <%@ Master Language="C#" Inherits="System.Web.Mvc.ViewMasterPage<MvcCatalog.Models.ViewModelBase>" %>
    <h1><%= Html.Encode(Model.SiteHeaderText) %></h1>
  7. Use Custom HTML Helper Extensions
    Use html helper extension methods for complex rendering logic.  I first started using this technique when I needed to add some functionality to navigation menu items on a master page.  Initially it was an unordered list containing links generated using Html.ActionLink.  The current page’s menu item needed to have a different CSS class.  Custom HTML Helper to the rescue.  (Originally I found a variation of this at http://www.asp.net/learn/mvc/tutorial-27-cs.aspx  )
    public static class MenuItemHelper
    {
        public static string MenuItem(this HtmlHelper helper, string linkText, string actionName, string controllerName)
        {
            string currentControllerName = (string)helper.ViewContext.RouteData.Values["controller"];
            string currentActionName = (string)helper.ViewContext.RouteData.Values["action"];
    
            // Add selected class
            if (currentControllerName.Equals(controllerName, StringComparison.CurrentCultureIgnoreCase) && currentActionName.Equals(actionName, StringComparison.CurrentCultureIgnoreCase))
                return string.Concat("<li class=\"selected\">", helper.ActionLink(linkText, actionName, controllerName), "</li>");
    
            // Add link
            return string.Concat("<li>", helper.ActionLink(linkText, actionName, controllerName), "</li>");
        }
    }
    <ul id="menu">              
        <%= Html.MenuItem("Home", "Index", "Home")%>
        <%= Html.MenuItem("Catalog", "Index", "Category")%>
        <%= Html.MenuItem("About", "About", "Home")%>
    </ul>
  8. Use Custom Routing Extensions
    I like all my URLs to be lower case, but I don’t want to change my controller and action methods to be lower case.  The use of a RoutingCollection extension method easily solves this.  Found this nifty extension method at: http://goneale.com/2008/12/19/lowercase-route-urls-in-aspnet-mvc/ 

    routes.MapRoute(
        "Default",                                            
        "{controller}/{action}/{id}",                         
        new { controller = "Home", action = "Index", id = "" }
    );
    Using the normal “MapRoute” method as in the snippet above would create a URL structure like “Product/Detail/binder-holder”. 
    routes.MapRouteLowercase(
        "Default",                                            
        "{controller}/{action}/{id}",                         
        new { controller = "Home", action = "Index", id = "" }
    );
    Using the modified “MapRouteLowerCase” extension method creates a URL like “product/detail/binder-holder”.
  9. Separate Data Access Logic and Business Logic from the Controller
    The controller is really just for presentation layer management logic.  It should decide what view gets rendered and hand that view the appropriate model data.  I prefer to use the repository pattern to separate the data access logic from the controller.  I also like to use a repository interface so that it can be swapped easily with a different data access method without affecting the controller.  In this case I used manual dependency injection, but an IOC framework could be used.
    public interface ICategoryRepository
        {
            void Add(MvcCatalog.Models.Category category);
            System.Collections.Generic.IEnumerable<MvcCatalog.Models.Category> GetCategories();
            string GetCategoryName(string id);
            void Save();
        }
    ICategoryRepository categoryRepository = new CategoryRepositoryLinqToSQL();
    
    public ActionResult Index()
    {
        var viewmodel = new Models.CategoryIndexViewModel();
        viewmodel.Categories = categoryRepository.GetCategories();
        return View(viewmodel);
    }
  10. Cache Your Data  
    A substantial performance gain can be made by not hitting your database for every request.  Again here is another good reason to use the repository pattern.
    public class CategoryRepositoryCached : ICategoryRepository
    {
        private const string cacheName = "Categories";
        ICategoryRepository _repository;
    
        public CategoryRepositoryCached() 
            : this(new CategoryRepositoryLinqToSQL())
        {}
    
        public CategoryRepositoryCached(ICategoryRepository repository)
        {
            _repository = repository;
        }
    
        #region ICategoryRepository Members
    
        public void Add(Category category)
        {
            _repository.Add(category);
        }
    
        public IEnumerable<Category> GetCategories()
        {
            var categories = (IEnumerable<Category>) HttpContext.Current.Cache[cacheName];
            if (categories == null)
            {
                categories = _repository.GetCategories();
                HttpContext.Current.Cache[cacheName] = categories;
            }
    
            return categories;
        }
    
        public string GetCategoryName(string id)
        {
            return _repository.GetCategoryName(id);
        }
    
        public void Save()
        {
            _repository.Save();
            HttpContext.Current.Cache.Remove(cacheName);
        }
    
        #endregion
    }
  11. jQuery + JSON Action Methods = Cool
    It is easy to return a JSON object instead of a view.
    public JsonResult Create(string CategoryName)
    {
        var category = new Models.Category();
        category.Name = CategoryName;
        category.URLName = CategoryName.ToLower().Replace(" ", "-");
        categoryRepository.Add(category);
        categoryRepository.Save();
    
        return Json(category);
    }
    <script type="text/javascript" language="javascript">
        $("#CreateNewCategory").click(function() {
            $.getJSON("/category/create/",
                      { "CategoryName": $("#NewCategoryName").val() },
                      CategoryAdded);
                  });
    
                  function CategoryAdded(category) {
                      $("#CategoryList").append("<li><a href=\"" + category.URLName + "/cat\">" + category.Name + "</a></li>");
                  }
    </script>
  12. (When using IIS 6) Use httphandlers and httpmodules for http compression and client side static file caching
    The problem with using wildcard mapping under IIS6 is that you loose a lot of IIS functionality like http compression and client side static file caching.  I use this nifty work around: http://code.msdn.microsoft.com/fastmvc
  13. Cache Appropriate Actions
    It can be useful to cache the rendered action results of pages that do not change very often.
    public class HomeController : Controller
    {
        [OutputCache(Duration=86400, VaryByParam="none")]
        public ActionResult Index()
        {
  14. Restricting Post Data Binding / UpdateModel
    Be careful when using UpdateModel to bind posted form values to an object.  Let’s say that you want to allow a user to edit a product while restricting them from changing the price.  Even if you don’t include an input box on your form someone could fake a form post.  There are several ways to protect against this.

    One way is to give a property exclude list to the UpdateModel method.  Here are those pesky magic strings again. 
    UpdateModel(prod, null, null, new[] { "Price" });
    I prefer the strongly typed method of defining an interface that only has the properties that should be bound.
    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult Edit(int id, FormCollection form)
    {
        var prod = productRepository.GetProductByID(id);
        try
        {
            UpdateModel<Models.IProductEdit>(prod);
            productRepository.Save();
  15. Note on Html Helper Magic Strings
    Again I think that magic strings should be avoided, but the default Html Helpers are full of them.  One approach is to use constants to contain the strings to one spot.  Another approach that is available in MVC Futures uses lambda expressions.  You could have something like this. 
    <%= Html.ActionLink<HomeController>(c => c.Index()) %>
    Instead of.
    <%= Html.ActionLink("Home", "Index", "Home") %>
    The only problem is that this approach uses compiled lambda expressions which can have performance/scaling issues.  It is my understanding that these issues have been fixed in ASP.NET MVC v2 (thanks for the update Elijah Manor).

 

Download

Keep in mind that my sample project is not 100% best practices.  I was trying to start simple then refactoring toward better practices.  You can download the sample below (the sample product pictures come from the Microsoft MVC StoreFront sample).

ASP.NET MVC Sample Download

Currently rated 3.3 by 111 people

  • Currently 3.297298/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:

Using Paint.NET to Blend Images

by michael 3/22/2009 2:14:41 AM

First Image Second Image

Sometimes I need to do a little graphics work, but I do not have Photoshop.  Instead I use a great free tool called Paint.NET.  It is an open source image editing project built with C#.  It has a very rich feature set in many ways similar to Photoshop.  Community plugins are also available.

Like other graphics tools, sometimes you have to figure out the tricks to get things done.  In this case I will be showing one way to seamlessly blend the edges of two photos.  I needed to do this for some scrolling banner images, but there are many other uses for this technique.

First you want to open both images.  Then expand the canvas on the first image in order to fit the second image.  This is done by selecting the “Image” menu item, and then the “Canvas Size” sub item.

Expand Canvas

Now copy the second image and paste it onto the second image into a new layer.  You can use the “Paste in to New Layer” option under the “Edit” menu.  Move the edge of the second image over the top of the first image.  You will need a good amount of overlap to blend with.  (The “Move Selection” mode is activated by clicking on second item at the top in the bottom right “Tools” bar.)

Overlap Second Image

Now select the gradient tool.  Set the gradient mode to “Transparency Mode”.  Set the Secondary transparency to 0.  Set the Primary transparency to 78 (Note: you may have to experiment with different levels of transparency).

Setup Transparency Gradient

Apply the gradient by clicking and dragging to the right (Note: make sure “Layer 2” is selected.  We are applying the gradient to this layer only).  You may need to redo this a few times to get the proper distance.  Notice that the first image is now bleeding into the second.

Apply Gradient

There is still one problem left.  Even though the images are somewhat merged there is a distinct line separating them.

Distinct Line Showing

One way to deal with this is to apply a blur.  There are many different ways to do this.  Sometimes a “Radial Blur” is best, and other times a “Motion Blur” works better.  It may be necessary to apply multiple blurs.  In this case a radial blur will be applied and then a motion blur (Note: the blurs are only being applied to the semitransparent edge of “Layer 2”).  First select the area to blur.

Select Area To Blur

Blur options are available under the “Effects” menu and then under the “Blur” sub menu.  First apply a radial blur.  Just experiment with the settings until you find something that looks good.  I used the settings below.

Blur Settings

After applying the radial blur you will notice that only a slight line is remaining.

Only slight line remaining

Select an area for a motion blur.

Select area for motion blur

Apply a small motion blur.

Apply Motion Blur

And finally we have merged and blended image edges.  The image transition is almost seamless.

Final Blended Image

I hopes this helps someone else trying to do this.  There are probably many other ways to do it.  This is just the approach that I took.

Currently rated 3.7 by 53 people

  • Currently 3.698115/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:

SQL Server 2008 – Filestream Datatype Presentation

by michael 1/12/2009 1:39:39 AM

I will be doing a small presentation tonight at the Fort Smith .NET User Group.  I am a little nervous since I have never done any public speaking.  Well you have to start sometime.  Anyway I wanted to go ahead and post some reference material.

 

Great White Paper by Paul Randal:

http://msdn.microsoft.com/en-us/library/cc949109.aspx

Performance Paper by Microsoft Research:

http://research.microsoft.com/apps/pubs/default.aspx?id=64525

C# Stored Videos Sample and Webcast by Microsoft Developer & Platform Evangelism:

http://www.codeplex.com/SQLSrvE2E/Wiki/View.aspx?title=SQL2K8%20FILESTREAM-WPF-HTTP%20Sample&referringTitle=Home

VB.NET Stored Pictures Sample by Dave Noderer (used a modified version of this for my presentation):

http://geekswithblogs.net/dnoderer/archive/2008/11/05/sql-server-2008-filestream-and-vb.net.aspx

VB.NET Stored Documents Sample by Mike Taulty:

http://mtaulty.com/CommunityServer/blogs/mike_taultys_blog/archive/2008/09/08/10729.aspx

Currently rated 3.0 by 20 people

  • Currently 3/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:

Great Time At DevLink 2008

by michael 8/28/2008 2:36:17 PM

I had a wonderful time at DevLink last weekend, though I am just now recuperating. I must be getting old or something.  Anyway it is something to definitely add to the yearly calendar.

Getting There:

Having company makes long trips a lot more digestible.  I had a great time on the drive with David Mohundro and Randy Walker.  David, thanks again for driving.

BeforeDriveToDevLink

The night before the conference David and I went to eat at Bone Fish Grill.  This was the first time I had been to one.  It was very very good.  If you ever go there be sure to get the Bang Bang Shrimp appetizer.

Bang Bang Shrimp

I have never had a shrimp dish quite like it.

Anyway, on to the event:

Some of the sessions I attended:

  • Integrating WPF & WCF into Your Office Business Application by Tim Huckaby
    • Tim is an energetic speaker.  This was a good idea session / proof of concept.  He showed off some neat things you could do for automating Excel from a WPF action pane. 
    • He also showed some outlook integration,but his demo did have some malfunctions.  He was wanting to show a demo where: when you create a new email to a customer the customer sales information is retrieved via WCF and displayed in a WPF control.  For some reason he couldn't get it to replace the previous add-in.  I hope he gets a chance to post the sample code. 
    • The session also covered using Expression Designer to convert Adobe Illustrator files to XAML.
    • Tim stressed that as developer it is convenient to leverage open source app styles to give your WPF application a nice look without the need for advanced design skills.
  • The Scaling Habits of ASP.NET Applications by Richard Campbell
    • Richard sure knows his stuff.  He focused on using a formula to identify website performance.  Here is a good link to an article illustrating this.
    • Key Points:
      • Caching (too much) is not always the solution.
      • Be sure to work on the problems that degrade your performance the most.  Don't spend a lot of time re-coding the site to increase performance by 50% on 10% of the problem.
      • Browsers can only make a limited number of simultaneous requests.  Identify if any of your CSS or script files can be consolidated.
  • Multi-Threading with Silverlight 2.0 by Steve Porter
    • Discovered that multi-threading in Silverlight is almost the same as multi-threading in the rest of .NET.  :)
  • Silverlight 2.0: Styling and Skinning by Colin Neller
    • Colin gave an excellent presentation on styling and control templates.  This was a good illustration on how controls break down into their base components.  Expression Blend was utilized heavily.  He did things with Blend that I didn't even know were available.
  • WPF for Developers by Joe Wirtley
  • IN-Depth: Silverlight Deep Dive Part 2 by Todd Anglin
    • Todd covered isolated storage, DOM manipulation, and cross site scripting.  This was really good for me, because I had not dealt with any of these in Silverlight.  He also turned me on to an HTTP debugger called Fiddler that looks really handy.
  • Essence of LINQ (Advanced) by Charlie Calvert
    • This was a dissection of LINQ.  Charlie showed how the new language additions of anonymous types, partial methods, and Lambda expression were critical in the development of LINQ.  He showed how to look at the LINQ expression tree using the Expression Tree Visualizer.  This could come in handy for doing your own LINQ extensions.

Open Spaces:

I did not attend any of the Open Spaces sessions, but I wish that I had.  There seemed to always be a traditional session I wanted to attend.  I will definitely have to check this out next time.  David Mohundro posted a review on his blog referencing the Open Spaces if you want to know more.

 

The People:

It's always good to meet new interesting people at these events.  A bunch of us went out to eat sushi at Aya Sushi after the first day.  At first we were a little worried, because it was in an alley and we were the only customers.  It turned out to be a good place, and I think we were just there at an off time.  They apparently take pictures of the customers to post on their MySpace page.

Aya Sushi

 

Technorati Tags:

Currently rated 3.0 by 30 people

  • Currently 3/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:

TrueCrypt 6a - System Encryption Benchmarks

by michael 8/13/2008 2:14:01 PM

TrueCrypt is a wonderful encryption package and best of all its free.  Many people already use it to encrypt thumb drives and to setup encrypted file stores. 

TrueCrypt has had system encryption (boot drive encryption) since version 5.  This is a similar technology to Vista BitLocker.  The entire boot drive is encrypted.  Before your operating system loads you have to enter a password.  This means you don't have to worry about the page file containing your encryption keys after shutdown.

I will be doing some traveling soon, and I was a little concerned about the safety of my data.  You hear all kinds of news stories recently involving theft of laptops.  With TrueCrypt you can do an easy in-place conversion of your existing system drive.  It also allows you to convert it back.  This convinced me to go ahead and give it a try after fully backing up my system. 

I need a very responsive system for development, so the possible performance impact worried me.  This of course leads to benchmarks.  I used the hard drive benchmarks included  in PC Wizard 2008.

Computer Stats:

Processor : AMD Turion 64 X2 Mobile TL-60 @ 2000 MHz

Ram : 2Gb

HDD : SATA 250 GB (5400 rpm)

Encryption Standard : AES (Best Performance)

Before Encryption:

1

After Encryption:

4

As you can see there is a decent performance drop mainly on the buffered IO.  CPU usage is higher during IO operations (encrypting and decrypting).  Qualitatively I haven't noticed much of a difference except slightly on bootup.  I would say TrueCrypt is a pretty good choice if you need a secure system, though you may want to have a decently powerful system.  It does utilize multiple cores so that helps.

You can download TrueCrypt here.

Currently rated 3.3 by 31 people

  • Currently 3.322581/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:

ASP.NET WebControl ClientID Bloat

by michael 8/11/2008 2:29:00 PM

When you have a large control hierarchy this can lead to very large rendered ClientIDs.

The following illustrates what is rendered when you have a label within a GridView row within a UserControl within a Repeater.

<span id="ctl00_ContentPlaceHolder1_SampleRepeaterWithDescriptiveName_ctl00_SampleWebUserControlWithDescriptiveName_GridViewWithDescriptiveName_ctl02_Label1WithDescriptiveName">Sue 1</span>

This can greatly effect the page size especially if the Repeater or GridView has a lot of rows.

One way to take care of this is to override the ClientID property of the control.  Just create a server control that inherits from the WebControl.  Override the ClientID and UniqueID properties.  Use a hashcode of the string instead of the string itself.

Imports System.Web.UI.WebControls
Public Class LabelExtended
    Inherits Label
    Public Overrides ReadOnly Property ClientID() As String
        Get
            Return MyBase.ClientID.GetHashCode
        End Get
    End Property
    Public Overrides ReadOnly Property UniqueID() As String
        Get
            Return MyBase.UniqueID.GetHashCode
        End Get
    End Property
End Class

The output using the extended label is much more reasonable.

<span id="-819157441">Sue 1</span>

This took a sample page from 381 KB to 138 KB.  You can download the sample here.

I have a slight concern that the hashcodes may not always be unique.  They probably will be unique in the string ranges that would be generated in this case.  It might be better to use the hashcode generators found in the cryptopgraphy namespace.

I would be interested if anyone else has a better solution for creating shorter ClientIDs.

Currently rated 2.9 by 16 people

  • Currently 2.875/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:

.NET Framework 3.5 SP1 and Visual Studio 2008 SP1 Released Today!

by michael 8/11/2008 8:18:33 AM

I have been using the very stable Beta, but a full release makes me feel a lot more comfortable.

VS 2008 SP1 Download

.NET Framework SP1 Download

Currently rated 2.8 by 11 people

  • Currently 2.818182/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:

Using XMLTextReader and DataSets to easily Data Mine Google News with very few lines of code.

by michael 7/10/2008 11:09:13 AM

Imports:
Imports System.Xml
Imports System.Data
 
Example Function:
Private Function ExtractGoogleNewsRSS(ByVal strSearchString As String) As Generic.List(Of NewsItem)
    Dim NewsItems As New List(Of NewsItem)
    Dim strSearchURL As String = String.Concat("http://news.google.com/news?hl=en&ned=us&q=", strSearchString, "&ie=UTF-8&output=rss")
    Using reader As XmlTextReader = New XmlTextReader(strSearchURL), _
          ds As New DataSet


        Dim dt As DataTable

        ds.ReadXml(reader)
        dt = ds.Tables(3)

        For Each row As DataRow In dt.Rows
            Dim itm As New NewsItem

            itm.Title = row("title")
            itm.PublishDate = row("pubdate")
            itm.Description = row("description")
            itm.URLString = row("link")

            NewsItems.Add(itm)
        Next
    End Using

    Return NewsItems
End Function

Private Class NewsItem
    Private _title As String
    Private _publishDate As Date
    Private _description As String
    Private _uRLString As String

    Public Property Title() As String
        Get
            Return _title
        End Get
        Set(ByVal value As String)
            _title = value
        End Set
    End Property

    Public Property PublishDate() As Date
        Get
            Return _publishDate
        End Get
        Set(ByVal value As Date)
            _publishDate = value
        End Set
    End Property

    Public Property Description() As String
        Get
            Return _description
        End Get
        Set(ByVal value As String)
            _description = value
        End Set
    End Property

    Public Property URLString() As String
        Get
            Return _uRLString
        End Get
        Set(ByVal value As String)
            _uRLString = value
        End Set
    End Property
End Class

You can easily load the Google News RSS data into an "XmlTextReader".  The "ReadXml" method of the "DataSet" converts the xml data into a "DataSet".  The "NewsItem" class is just an example data container.

Currently rated 2.9 by 14 people

  • Currently 2.857143/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:

SignTool Error: Signtool requires CAPICOM version 2.1.0.1

by michael 3/12/2008 10:36:29 AM

I had uninstalled some CTP "Community Technology Preview" software.  The next thing I know I'm getting this "SignTool" error when trying to publish with ClickOnce in Visual Studio 2005.  It wasn't a hard fix.

  1. Download the latest CAPICOM "Platform SDK Redistributable" here.
  2. Run the downloaded "capicom_dc_sdk.msi" file.
  3. I had to register the DLL file.  Assuming the installation directory is the same just run the following command from the command prompt.

regsvr32 "C:\Program Files\Common Files\Microsoft Shared\CAPICOM\CapiCom.dll"

Hope this helps!

Currently rated 3.3 by 44 people

  • Currently 3.295455/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:

Michael Johnson Michael Johnson
Developer and Technologist.

E-mail me Send mail

Pages

    Recent comments

    Categories

    None


    Disclaimer

    The opinions expressed herein are my own personal opinions and do not represent my employer's view in anyway.

    © Copyright 2014

    Sign in