Windows Live Writer and BlogEngine 1.5 Image Upload Issue

I upgraded to the really cool BlogEngine 1.5 last week. I was surprised to find out that I was three versions behind. Nevertheless, the guys behind BlogEngine always know how the make the upgrade really easy!

When I tried to publish a blog posting using Windows Live Writer, I came across two problems. The first problem I had was the dreaded “Object reference not set to an instance of an object” error. I really hate this error! This has to be the most useless error message in .NET!

The second problem I came across was the inability to upload images and the following error occurred:

WLWImageUploadError

After some good old research on the web and reading various BlogEngine Discussion forums, fixing these errors is as straight-forward as installing BlogEngine.

To fix the “Object reference not set to an instance of an object” error all you have to do is create a new blog account in Windows Live Writer. Just updating your account configuration will not resolve this issue. You have to setup a new account. I think this will update the wlwmanifest.xml file in your site directory. Once you have successfully tested you can publish a blog post with your new account, delete your old account.

The image upload issue is caused by permissions restrictions to your App_Data folder. Make sure you have allowed read/write permissions to this folder. For some reason adding read/write permissions to the App_Data folder through my FTP client did not work. The only way I was able to set the permissions is through my Hosting Plan File Manager account.

Mobile for 4 Year Olds? This Is No Toy!

firefly When the mobile phone first came out, not surprisingly they took the world by storm. Over the years, the mobile has evolved and it was only going to be a matter of time before a phone for a child would be released.

The Firefly mobile phone for four-year-olds has the ability to take pictures, video’s and play MP3 files while allowing parents to have full control. They can restrict who can be called from the phone, who can call the phone and control how much is spent. This is all well and good, but I am finding quite hard to understand why a child of four would ever need a mobile? Isn’t it the parents, teachers or guardians responsibility to ensure that the child is safe? Targeting a mobile phone for four-year-olds raises the question on where the parents responsibility is going.

I remember back in the good old days when I was a kid, my parents were definitely the over-protected type (and they still are). But they always made sure they knew my whereabouts and I was always in the company of an responsible adult to keep an eye over my mischievous ways. Have things changed so much since I was a young kid (I am 24 now) that there is now a need for toddlers to have mobiles? The answer is NO! Only the bank balance of mobile phone companies will be benefiting from this idea.

I have to admit the Firefly mobile phone makers have a very clever marketing team. They are just playing on the fear that all parents have. Losing sight of their child. If you don’t know where your four-year-old is, will he/she know? Four-year-olds rarely have information to impart of such significance on their surroundings that will help in locating where they are.

We have all been made aware of the health concerns on the impact of mobile phone radiation. We as adults know the consequences of prolonged use a mobile phone can have on our brains and have the freedom of choice to decide how long we wish use them. What about a child? They do not have the knowledge to make such a choice? A disturbing study by researchers at Örebro University Hospital in Sweden last year indicated that children may be five times more likely to get brain cancer if they use mobile phones.

I could carry on moaning about this mobile phone. I can see no reason a child young as four to have a mobile phone.

Use YouTubes RSS Feed To Output A List of Videos

Ok! I admit it! I posted some incorrect information from one of my previous blog posts to “Dynamically Output A List of YouTube Video’s In ASP.NET”. I stupidly said: “The RSS feed is not structured in a nice enough format to output all the information you may need with ease.” I must have been drunk when I wrote that. As you can see from a sample of their RSS feed below I was wrong:

<entry>
  <id>http://gdata.youtube.com/feeds/api/videos/R6r2ckeIpic</id>
    <published>2009-05-31T17:01:12.000Z</published>
    <updated>2009-06-01T01:22:11.000Z</updated>
    <category scheme='http://gdata.youtube.com/schemas/2007/keywords.cat' term='bike'/>
    <category scheme='http://gdata.youtube.com/schemas/2007/keywords.cat' term='Podcast'/>
    <category scheme='http://gdata.youtube.com/schemas/2007/keywords.cat' term='Pedrosa'/>
    <category scheme='http://gdata.youtube.com/schemas/2007/keywords.cat' term='motorcycles'/>
    <category scheme='http://gdata.youtube.com/schemas/2007/keywords.cat' term='Honda+RC212V'/>
    <category scheme='http://gdata.youtube.com/schemas/2007/keywords.cat' term='speed'/>
    <category scheme='http://gdata.youtube.com/schemas/2007/keywords.cat' term='Suzuki+GSV-R800'/>
    <category scheme='http://schemas.google.com/g/2005#kind' term='http://gdata.youtube.com/schemas/2007#video'/>
    <category scheme='http://gdata.youtube.com/schemas/2007/categories.cat' term='Sports' label='Sport'/>
    <category scheme='http://gdata.youtube.com/schemas/2007/keywords.cat' term='Rossi'/>
    <category scheme='http://gdata.youtube.com/schemas/2007/keywords.cat' term='motorcycle+road+racing'/>
    <category scheme='http://gdata.youtube.com/schemas/2007/keywords.cat' term='motograndprix'/>
    <category scheme='http://gdata.youtube.com/schemas/2007/keywords.cat' term='Yamaha+YZR+M1'/>
    <category scheme='http://gdata.youtube.com/schemas/2007/keywords.cat' term='Mugello'/>
    <category scheme='http://gdata.youtube.com/schemas/2007/keywords.cat' term='Italy'/>
    <category scheme='http://gdata.youtube.com/schemas/2007/keywords.cat' term='Stoner'/>
    <category scheme='http://gdata.youtube.com/schemas/2007/keywords.cat' term='Ducati+Desmosedici+GP8'/>
    <category scheme='http://gdata.youtube.com/schemas/2007/keywords.cat' term='MotoGP'/>
    <category scheme='http://gdata.youtube.com/schemas/2007/keywords.cat' term='Lorenzo'/>
    <title type='text'>MotoGP action from Mugello 2009</title>
    <content type='text'>The best of the action from the Gran Premio D&amp;#180;Italia Alice, the fifth round of the 2009 motogp World Championship.</content>
    <link rel='alternate' type='text/html' href='http://www.youtube.com/watch?v=R6r2ckeIpic'/>
    <link rel='http://gdata.youtube.com/schemas/2007#video.responses' type='application/atom+xml' href='http://gdata.youtube.com/feeds/api/videos/R6r2ckeIpic/responses'/>
    <link rel='http://gdata.youtube.com/schemas/2007#video.related' type='application/atom+xml' href='http://gdata.youtube.com/feeds/api/videos/R6r2ckeIpic/related'/>
    <link rel='self' type='application/atom+xml' href='http://gdata.youtube.com/feeds/api/users/motogp/uploads/R6r2ckeIpic'/>
    <author>
      <name>MotoGP</name>
      <uri>http://gdata.youtube.com/feeds/api/users/motogp</uri>
    </author>
    <gd:comments>
      <gd:feedLink href='http://gdata.youtube.com/feeds/api/videos/R6r2ckeIpic/comments' countHint='24'/>
    </gd:comments>
    <media:group>
      <media:category label='Sport' scheme='http://gdata.youtube.com/schemas/2007/categories.cat'>Sports</media:category>
      <media:description type='plain'>The best of the action from the Gran Premio D&amp;#180;Italia Alice, the fifth round of the 2009 motogp World Championship.</media:description>
      <media:keywords>MotoGP, Italy, Mugello, Podcast, Stoner, Pedrosa, Rossi, Lorenzo, Yamaha+YZR+M1, Ducati+Desmosedici+GP8, Honda+RC212V, Suzuki+GSV-R800, motorcycle+road+racing, motograndprix, motorcycles, bike, speed</media:keywords>
      <media:player url='http://www.youtube.com/watch?v=R6r2ckeIpic'/>
      <media:thumbnail url='http://i.ytimg.com/vi/R6r2ckeIpic/2.jpg' height='90' width='120' time='00:00:38.500'/>
      <media:thumbnail url='http://i.ytimg.com/vi/R6r2ckeIpic/1.jpg' height='90' width='120' time='00:00:19.250'/>
      <media:thumbnail url='http://i.ytimg.com/vi/R6r2ckeIpic/3.jpg' height='90' width='120' time='00:00:57.750'/>
      <media:thumbnail url='http://i.ytimg.com/vi/R6r2ckeIpic/0.jpg' height='240' width='320' time='00:00:38.500'/>
      <media:title type='plain'>MotoGP action from Mugello 2009</media:title>
      <yt:duration seconds='77'/>
    </media:group>
    <yt:noembed/>
    <gd:rating average='4.862069' max='5' min='1' numRaters='29' rel='http://schemas.google.com/g/2005#overall'/>
    <yt:statistics favoriteCount='10' viewCount='1055'/>
</entry>
<entry>
    ...
</entry>
<entry>
    ...
</entry>

Each “entry” element within the RSS feed represents a YouTube video. You are able to extrapolate all the important information about each movie such as Average Score, View Count, Thumbnail Images, Video Description, etc. Really useful stuff!

You may be thinking: Why should I use an RSS feed to retrieve the video information rather than using the YouTube API? Well, using a YouTube API is definitely the easier and most straight-forward method. But what you should be aware that the API only works from .NET 2.0 onwards. There isn’t a YouTube API for .NET 1.1. Unfortunately, I only found this out when I tried to implement the API into one of my .NET 1.1 client sites.

The code I have written below, reads the YouTube RSS feed and stores the information in a DataTable.

private void GetYouTubeData(string YouTubeUrl)
{
    //Create DataTable to store specific YouTube information
    DataTable dtYouTubeVideoData = new DataTable();
    dtYouTubeVideoData.Columns.Add("YouTubeID");
    dtYouTubeVideoData.Columns.Add("Title");
    dtYouTubeVideoData.Columns.Add("Description");
    dtYouTubeVideoData.Columns.Add("ImageUrl");
    dtYouTubeVideoData.Columns.Add("AverageRatings");
    dtYouTubeVideoData.Columns.Add("ViewCount");

    DataRow drYouTubeVideoData;

    //Link to YouTube RSS feed
    XmlTextReader rssReader = new XmlTextReader(YouTubeUrl);
    XmlDocument xmlDoc = new XmlDocument();

    //Download the XML (via the XmlTextReader)
    xmlDoc.Load(rssReader);

    //Select all nodes starting with "entry"
    XmlNodeList xmlNodeList = xmlDoc.GetElementsByTagName("entry");
    
    //For each "entry" element found
    foreach (XmlNode node in xmlNodeList)
    {
        drYouTubeVideoData = dtYouTubeVideoData.NewRow();

        //Create a new document, to search through the inner contents
        XmlDocument innerXmlDocument = new XmlDocument();
        innerXmlDocument.LoadXml(node.OuterXml);

        // Get movie ID
        drYouTubeVideoData["YouTubeID"] = innerXmlDocument.GetElementsByTagName("id")[0].InnerText.Replace("http://gdata.youtube.com/feeds/api/videos/", "");

        // Get movie title
        drYouTubeVideoData["Title"] = innerXmlDocument.GetElementsByTagName("title")[0].InnerText;

        //Get movie description
        drYouTubeVideoData["Description"] = innerXmlDocument.GetElementsByTagName("content")[0].InnerText;
        
        //Get the thumbnails
        XmlNodeList mediaTumbnail = innerXmlDocument.GetElementsByTagName("media:thumbnail");

        //Iterate through each thumbnail and only get one thumbnail per <entry>.
        foreach (XmlNode thumbnailNode in mediaTumbnail)
        {
            if (thumbnailNode.Attributes["height"].Value == "90" && thumbnailNode.Attributes["url"].Value.EndsWith("1.jpg"))
            {
                drYouTubeVideoData["ImageUrl"] = thumbnailNode.Attributes["url"].Value;
            }
        }

        //Get movie rating
        XmlNodeList ratings = innerXmlDocument.GetElementsByTagName("gd:rating");

        foreach (XmlNode ratingsNode in ratings)
        {
            drYouTubeVideoData["AverageRatings"] = ratingsNode.Attributes["average"].Value;
        }

        //Get Statistics
        XmlNodeList statistics = innerXmlDocument.GetElementsByTagName("yt:statistics");

        foreach (XmlNode statisticsNode in statistics)
        {
            drYouTubeVideoData["ViewCount"] = statisticsNode.Attributes["viewCount"].Value;
        }

        dtYouTubeVideoData.Rows.Add(drYouTubeVideoData);
    }

    rssReader.Close();

    //Bind YouTube data to repeater
    repVideoList.DataSource = dtYouTubeVideoData;
    repVideoList.DataBind();        
}

How To Ensure A Refreshed Web Page Is Not Cached?

BrowserRefresh Being a fellow Web Developer, you would probably agree with me when I say that the “Refresh” button is the most used button in your browser. I can’t even consider about counting the amount of times I hit the “Refresh” button while creating a web page.

On the odd occasion when I am having a really bad day and nothing seems to be going my way. I am bound to be irritated even further because my browser is being really stupid and does not allow me to see the changes I have made to a web page I am working on. Its almost like the browser is trying to mock me and make my web developing life and living HELL!!!!!

So I carry out the following methods to get my page to refresh.

Force Refresh

In many cases in order to see changes on your page you would press the “Refresh” button (or F5), which simply reloads the page without clearing the cache. So you will have to carry out a Force Refresh by pressing Ctrl + F5.

Clearing Cache In Settings

If the Force Refresh does not work. You will have to carry out some serious cleaning by going into the browser settings.

  • Mozilla FireFox – Tools > Options > Privacy > Private Data section > Settings
  • Microsoft Internet Explorer – Tools > Internet Options > Temporary Files > Delete Temporary Files

Adding “?” To End of The WEB address

This is probably my most favourite method of ensuring a page you are viewing is not cached. All you need to do is add a “?” to the end of the web address. For example:

?

The browser thinks that you are requesting a new page. This works great if all else fails! You can even add another “?” to the end of the web address to carry out another non-cached refresh.

No Internet Explorer In Windows 7

internetexplorer7 I was surprised to hear from one of the news sites today that the new version of Windows operating system, called Windows 7 will come without a browser. This gives the hardware manufacturer’s the freedom to choose alternative browsers such as FireFox, Opera, and Safari.

This is all well and good. Definitely a step in the right direction to show the European Union regulators that they are willing to change its “abusive” behaviour in the market. But there is one thing that perplexes me. What happens when someone decides to purchase a copy of Windows 7 themselves? How are they going to access the Internet without a web browser preinstalled to download one of the alternatives? If anyone knows the answer to this, I will be very interested to know!

Dynamically Output A List of YouTube Videos In ASP.NET

I recently needed to dynamically display a list of YouTube video’s from a specific YouTube account. If you plan to output the list of video’s straight from the YouTube’s RSS feed into your .NET application don’t bother. The RSS feed is not structured in a nice enough format to output all the information you may need with ease. For example, video ratings, time, etc are all in the same XML block.

As you can see from the screenshot below, the ASP.NET page I created outputs all the information that you will probably want to show (if it doesn’t then it should give you a good starting point).

YouTubeReaderScreenshot

Before creating your own custom YouTube .NET application you will need to carry out two things:

  1. Go to the YouTube API Toolswebsite and download the “Google Data API SDK”. Once you have installed this on your computer. You will need to copy three dll’s from one of the sample projects:

    • Google.GData.Client.dll
    • Google.GData.Extensions.dll
    • Google.GData.YouTube.dll

    These dll's can be copied to your new project.

  2. Register a Developer Key. This is important! Without the developer key, your custom YouTube application will not work.

To create the page (above), copy the following code:

ASPX.CS Page

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Xml;
using System.Net;
using System.IO;
using System.Text.RegularExpressions;
using Google.GData.Client;
using Google.GData.Extensions;
using Google.GData.Extensions.MediaRss;
using Google.YouTube;
using Google.GData.YouTube;
using System.Text;
using System.Data;

public partial class _Default : System.Web.UI.Page
{
    private string YouTubeChampionshipChannel;
    private string YouTubeClientID;
    private string YouTubeDeveloperKey;
    public string YouTubeMovieID;
    public DataTable dtVideoData = new DataTable();

    protected void Page_Load(object sender, EventArgs e)
    {
        //Pass User Name to the YouTube link
        YouTubeChampionshipChannel = "MotoGP";

        //Add the YouTube Developer keys.
        //Register a Developer Key at: http://code.google.com/apis/youtube/dashboard
        YouTubeClientID = "test";
        YouTubeDeveloperKey = "testabc123";

        CreateVideoFeed();

        //Assign the first video details on page load.
        if (String.IsNullOrEmpty(YouTubeMovieID))
        {
            YouTubeMovieID = dtVideoData.Rows[0]["VideoID"].ToString();
            lblDescription.Text = dtVideoData.Rows[0]["Description"].ToString();
        }

    }

    private void CreateVideoFeed()
    {
        YouTubeRequestSettings settings = new YouTubeRequestSettings("MotoGP Channel", YouTubeClientID, YouTubeDeveloperKey);
        YouTubeRequest request = new YouTubeRequest(settings);

        //Link to the feed we wish to read from
        string feedUrl = String.Format("http://gdata.youtube.com/feeds/api/users/{0}/uploads?orderby=published", YouTubeChampionshipChannel); ;
                
        dtVideoData.Columns.Add("Title");
        dtVideoData.Columns.Add("Description");
        dtVideoData.Columns.Add("DateUploaded");
        dtVideoData.Columns.Add("Ratings");
        dtVideoData.Columns.Add("NoOfComments");
        dtVideoData.Columns.Add("VideoID");
        dtVideoData.Columns.Add("Duration");

        DataRow drVideoData;

        Feed<Video> videoFeed = request.Get<Video>(new Uri(feedUrl));

        //Iterate through each video entry and store details in DataTable
        foreach (Video videoEntry in videoFeed.Entries)
        {
            drVideoData = dtVideoData.NewRow();

            drVideoData["Title"] = videoEntry.Title;
            drVideoData["Description"] = videoEntry.Description;
            drVideoData["DateUploaded"] = videoEntry.Updated.ToShortDateString();
            drVideoData["Ratings"] = videoEntry.YouTubeEntry.Rating.Average.ToString();
            drVideoData["NoOfComments"] = videoEntry.CommmentCount.ToString();
            drVideoData["VideoID"] = videoEntry.YouTubeEntry.VideoId;
            drVideoData["Duration"] = videoEntry.YouTubeEntry.Duration.Seconds.ToString();

            dtVideoData.Rows.Add(drVideoData);            
        }

        repVideoList.DataSource = dtVideoData;
        repVideoList.DataBind();
    }

    protected void repVideoList_ItemDataBound(object sender, RepeaterItemEventArgs e)
    {
        if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
        {
            DataRowView drVideo = (DataRowView)e.Item.DataItem;

            LinkButton showVideo = (LinkButton)e.Item.FindControl("btnShowVideo");
            Literal title = (Literal)e.Item.FindControl("Title");
            Literal description = (Literal)e.Item.FindControl("Description");
            Literal ratings = (Literal)e.Item.FindControl("Ratings");
            Literal noOfComments = (Literal)e.Item.FindControl("NoOfComments");
            Literal duration = (Literal)e.Item.FindControl("Duration");

            showVideo.CommandArgument = drVideo["VideoID"].ToString();
            title.Text = drVideo["Title"].ToString();
            description.Text = drVideo["Description"].ToString();
            ratings.Text = drVideo["Ratings"].ToString();
            noOfComments.Text = drVideo["NoOfComments"].ToString();
            duration.Text = drVideo["Duration"].ToString();

        }
    }
    protected void repVideoList_ItemCommand(object source, RepeaterCommandEventArgs e)
    {
        // Pass the YouTube movie ID to flash
        YouTubeMovieID = e.CommandArgument.ToString();

        if (YouTubeMovieID == e.CommandArgument.ToString())
        {
            lblDescription.Text = ((Literal)e.Item.FindControl("Description")).Text;
        }

    }
}

ASPX Page

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
    <div style="margin: 10px;">
        <div style="float: left; width: 300px; height: 400px; overflow: scroll;">
            <asp:Repeater ID="repVideoList" runat="server" OnItemDataBound="repVideoList_ItemDataBound"
                OnItemCommand="repVideoList_ItemCommand">
                <HeaderTemplate>
                    <table>
                </HeaderTemplate>
                <ItemTemplate>
                    <tr>
                        <td>
                            <asp:LinkButton ID="btnShowVideo" runat="server">Show Video</asp:LinkButton>
                            <br>
                            <strong>
                                <asp:Literal ID="Title" runat="server"></asp:Literal></strong>
                            <br />
                            <asp:Literal ID="Description" runat="server"></asp:Literal>
                            <br />
                            Rating: <asp:Literal ID="Ratings" runat="server"></asp:Literal>
                            <br />
                            Comments: <asp:Literal ID="NoOfComments" runat="server"></asp:Literal>
                            <br />
                            Duration: <asp:Literal ID="Duration" runat="server"></asp:Literal>
                            <br />
                            <br />
                        </td>
                    </tr>
                </ItemTemplate>
                <FooterTemplate>
                    </table>
                </FooterTemplate>
            </asp:Repeater>
        </div>
        <div style="float: left; margin-left: 15px;width:600px;2">
            <object width="480" height="385" style="float: left; clear: both; margin-bottom: 10px;">
                <param name="movie" value="http://www.youtube.com/v/<%=YouTubeMovieID %>&hl=en&fs=1&rel=0">
                </param>
                <param name="allowFullScreen" value="true"></param>
                <param name="allowscriptaccess" value="always"></param>
                <embed src="http://www.youtube.com/v/<%=YouTubeMovieID %>&hl=en&fs=1&rel=0" type="application/x-shockwave-flash"
                    allowscriptaccess="always" allowfullscreen="true" width="480" height="385"></embed>
            </object>
            <div style="float: left;">
                <asp:Label ID="lblDescription" runat="server"></asp:Label>
            </div>
        </div>
    </div>
    </form>
</body>
</html>

This is just the beginning on what the YouTube API has to offer. For more information, visit the YouTube API website (http://code.google.com/apis/youtube/2.0/developers_guide_dotnet.html).

* Post Updated 18/06/2009 – You can output YouTube video’s via RSS feed *

Analyse Disk Fragmentation in Windows Vista

In Windows XP you had the option to analyse a disk drive you wished to defragment without carrying out a full disk defragmentation. Looking at the Windows Vista Disk Defragmenter GUI at face value I thought this feature was left out. After some research, I found that this  this feature has been included but you will be forgiven for not knowing where it is. Fortunately, using the command line tool does allow you to analyse a drive. It is as simple as typing the following:

  1. Open up Command Line tool.
  2. Type the following: defrag –a <disk drive letter>
  3. Press enter and you will see the following:
Microsoft Windows [Version 6.0.6000]
Copyright (c) 2006 Microsoft Corporation.  All rights reserved.

C:\Users\Surinder>defrag -a c:
Windows Disk Defragmenter
Copyright (c) 2006 Microsoft Corp.

Analysis report for volume C:

    Volume size                         = 298 GB
    Free space                          = 236 GB
    Largest free space extent           = 136 GB
    Percent file fragmentation          = 1 %

    Note: On NTFS volumes, file fragments larger than 64MB are not included in the fragmentation statistics

    You do not need to defragment this volume.

Neato!!

Embed Flash Movie 100% for Firefox and Internet Explorer

I needed a flash movie to displayed at 100% in my web page. I thought this will be a simple job. Just set the height and width attributes within my object tag to “100%”. This method worked fine for Internet Explorer but failed in Firefox. Firefox seemed to ignore my size settings that contained a percentage. After a lot of time wasting, I confirmed that Firefox does not like its height and width attributes measured in percentages and only likes measurements in pixels.

In order to fix this problem I needed to do the following:

  1. Write some JavaScript just for Firefox so that it will get the users screen resolution in pixels and add this into my object tag that contained my Flash movie.

    <script type="text/javascript" language="javascript">
        if (window.innerWidth)
        {
            // Get screen width and height minus scroll bars
            var width = window.innerWidth - 24;
            var height = window.innerHeight - 24;           
                
            //Find Flash movie
            var FlashMovie = document.getElementById('FlashMovie');           
    
            //Only assign width and height if browswer is not Internet Explorer
            if (navigator.appName.indexOf('Internet Explorer') == -1)
            {
                FlashMovie.height = height;
                FlashMovie.width = width;        
            }
        }       
    </script>
    
  2. Keep the height=”100%” width=”100%” object attributes. This will be needed for Internet Explorer.

    <object id="FlashMovie" type="application/x-shockwave-flash" height="100%" width="100%" data="myflash.swf">
    <param name="movie" value="myflash.swf" />
    <param name="wmode" value="transparent" />
    <p>
        No flash message
    </p>
    </object>
    

If anyone has any better idea on how to solve this problem. Please comment. Thanks!

Rename SharePoint Host Headers and Change Database Server Name

I currently have a SharePoint 2007 demonstration setup on a development environment. The SharePoint 2007 installation was originally setup for a specific client. So the host headers, computer name and farm credentials contained the client name. This all had to be changed. Carrying out another installation of SharePoint was something I did not want to do since I wanted to retain all the dummy data and sites.

You might be thinking: Why don’t I just change the host headers with the new client name? Well that’s because I am a bit OCD and I like everything to be consistent. Tongue out

To rename, carry out the following. But remember to carry out these steps exactly because you might come across the problem I did where I couldn’t get to Central Admin or view my Intranet:

  1. Go to Central Admin > Operations > Alternate Access Mappings.
  2. Change the host headers as required.
  3. If you changed the name of the server carry out the following command:

    stsadm -o renameserver -oldservername <oldname> -newservername <newname>
    
  4. Rename the server to a new server name by going to My Computer > Properties > Computer Name and restart.
  5. After restart you will need to update the farm login credentials since the computer name has been changed from Steps 3 and 4. If you do not update the farm credentials, you will get the dreaded “Cannot connect to database” message when trying to view your Intranet.

    stsadm -o updatefarmcredentials -userlogin <domain\user> -password <password>
    
  6. Change the site names in IIS. This site names will need to reflect the changes you made in Step 1.
  7. Change the host headers in the host file (C:\Windows\System32\drivers\etc\hosts).

ASP.NET Membership Provider - Validating Duplicate Email Addresses

ASP.NET Membership Provider makes implementing secure authenticating membership forms more straightforward. The ASP.NET Membership Provider contains so many useful methods. But I could not find a method within the Membership class to check whether there was an existing email address in the database even though you can state in the web.config (requiresUniqueEmail) file:

<membership>
  <providers>
    <add
      name="SqlMembershipProvider"
      type="System.Web.Security.SqlMembershipProvider, ..."
      connectionStringName="LocalSqlServer"
      enablePasswordRetrieval="false"
      enablePasswordReset="true"
      requiresQuestionAndAnswer="true"
      applicationName="/"
      requiresUniqueEmail="true"
      passwordFormat="Hashed"
      maxInvalidPasswordAttempts="5"
      minRequiredPasswordLength="7"
      minRequiredNonalphanumericCharacters="1"
      passwordAttemptWindow="10"
      passwordStrengthRegularExpression=""
    />
  </providers>
</membership>

I created the following CustomValidator with a ServerValidate event to carry out the duplicate email check:

protected void DuplicateEmailCheck_ServerValidate(object source, ServerValidateEventArgs args)
    {
        //Create MembershipUserCollection to collate a list of duplicate email addresses
        MembershipUserCollection memCollection = Membership.GetUserNameByEmail(args.Value.ToString());

        //If duplicate email addresses are found then error
        if (memCollection.Count > 0)
        {
            args.IsValid = false;
        }
        else
        {
            args.IsValid = true;
        }
    }