Wednesday, November 4, 2015

OData v4 Endpoint Using ASP.NET Web API 2.2 & Visual Studio 2015

In this tutorial, we will do the following:
  1. Create an empty web application in Visual Studio.
  2. Add a Student model and use Code First Entity Framework to create the database and seed it with sample data.
  3. Create an OData v4 controller, which will act as the OData service endpoint.
  4. Create a separate client console application that will access the OData service.
Let’s get started.

Creating the Server OData Student Service

We will first create a new web project in Visual Studio 2015.
File >> New > Project >> Installed >> Templates >> Visual C# >> Web
Select the ASP.NET Web Application template. Name the project "StudentService".

image

Visual Studio Extensions

We need to add two extensions that pertain the V4 of the OData standard, namely:
  1. OData v4 Web API Scaffolding
  2. OData v4 Client Code Generator
To install these extensions:
  • Tools >> Extensions and Updates…
  • Enter “odata” in the search box and install these two extensions:
image

Add a Model Class

In Solution Explorer, right-click the Models folder. From the context menu, select Add >> Class. Name the class Student. In the Student.cs file, replace the class code with the following:
public class Student {
  public int StudentId { get; set; }
  public string FirstName { get; set; }
  public string LastName { get; set; }
  public string Major { get; set; }
}
Entity Framework Code First
Install the NuGet package for EF. From the Tools menu, select NuGet Package Manager > Package Manager Console. In the Package Manager Console window, type:
Install-Package EntityFramework
In the Web.config file, add the following section after the closing </configSections> tag:
<connectionStrings>
   <add name="StudentDB" connectionString="Data Source=(localdb)\v11.0; 
   Initial Catalog=StudentDB; Integrated Security=True; MultipleActiveResultSets=True; 
   AttachDbFilename=|DataDirectory|StudentDB.mdf" 
   providerName="System.Data.SqlClient" />
</connectionStrings>
Note: If you are using localdb version 12, then the connection string data source would be: 
Data Source=(localdb)\mssqllocaldb.
Next, add a class named StudentContext to the Models folder:
public class StudentContext : DbContext {
   public StudentContext() : base("name=StudentDB") { }
   public DbSet<Student> Students { get; set; }
}

Migrations

1) To enable migrations run the following command in the Package Manager Console:
enable-migrations -ContextTypeName StudentContext -MigrationsDirectory Migrations\StudentMigrations
2) Open the Configuration.cs file in the /Migrations/StudentMigrations folder. Replace the Seed() method with the following code:
protected override void Seed(StudentContext context) {
  context.Students.AddOrUpdate(
  s => new { s.FirstName, s.LastName },
  new Student { FirstName = "Andrew", LastName = "Peters", Major = "Pharmacy" },
  new Student { FirstName = "Brice", LastName = "Lambson", Major = "Business" },
  new Student { FirstName = "Rowan", LastName = "Miller", Major = "Medicine" },
  new Student { FirstName = "Tom", LastName = "Doe", Major = "Engineering" },
  new Student { FirstName = "Bob", LastName = "Fox", Major = "City Planning" },
  new Student { FirstName = "Sue", LastName = "Ace", Major = "Forestry" },
  new Student { FirstName = "Joe", LastName = "Gad", Major = "Mining" },
  new Student { FirstName = "Sam", LastName = "Roy", Major = "Energy" }
  );
  context.SaveChanges();
}
3) Add a migration by running the following command in the Package Manager Console:
add-migration -ConfigurationTypeName StudentService.Migrations.StudentMigrations.Configuration "InitialCreate"
4) Next, we will create and seed the database by running this command in the Package Manager Console:
update-database -ConfigurationTypeName StudentService.Migrations.StudentMigrations.Configuration

Create OData Controller:

To the Controllers folder, add a controller and select “Microsoft OData V4 Web API Controller using Entity Framework”

image

Make the following choices on the “Add Controller” wizard:

image

Click on the Add button. The controller gets created.
Open the StudentsController. You will find this information in the class comment:
The WebApiConfig class requires additional changes. Merge these statements into the Register method of the WebApiConfig class as applicable. Note that OData URLs are case sensitive.
using System.Web.OData.Builder;
using System.Web.OData.Extensions;
using StudentService.Models;
ODataConventionModelBuilder builder = new ODataConventionModelBuilder();
builder.EntitySet<Student>("Students");
config.MapODataServiceRoute("odata", "odata", builder.GetEdmModel());

Run the server-side application

Hit Ctrl-F5 to run the web application in a browser at address /odata/Students. This should display:
Note: The URL is case-sensitive with OData.
{
  "@odata.context":"http://localhost:51103/odata/$metadata#Students","value":[
    {
      "StudentId":1,"FirstName":"Andrew","LastName":"Peters","Major":"Pharmacy"
    },{
      "StudentId":2,"FirstName":"Brice","LastName":"Lambson","Major":"Business"
    },{
      "StudentId":3,"FirstName":"Rowan","LastName":"Miller","Major":"Medicine"
    },{
      "StudentId":4,"FirstName":"Tom","LastName":"Doe","Major":"Engineering"
    },{
      "StudentId":5,"FirstName":"Bob","LastName":"Fox","Major":"City Planning"
    },{
      "StudentId":6,"FirstName":"Sue","LastName":"Ace","Major":"Forestry"
    },{
      "StudentId":7,"FirstName":"Joe","LastName":"Gad","Major":"Mining"
    },{
      "StudentId":8,"FirstName":"Sam","LastName":"Roy","Major":"Energy"
    }
  ]
}
Try out these additional endpoints after adjusting the port number to suit your environment:
/odata
/odata/$metadata
/odata/Students(3)

Create an OData v4 Client Console App


Keep the server application running. Start a new instance of Visual Studio and create an independent Console Application.

File >> Add > Project >> Installed >> Visual C# >> Console Application


Name the project StudentsClientApp.

Generate the Service Proxy

Right-click the StudentsClientApp console project. Select Add >> New Item >> Visual C# Items >> Code >> OData Client. 
Name the template "StudentClient.tt". 

image

Open the StudentClient.tt file. Set the value of MetadataDocumentUri to the metadata URL of your service. In the case of my example this would be:
public const string MetadataDocumentUri = http://localhost:58005/odata/$metadata;
Note: You must adjust the port number to match your environment.
Note: Needless to say, you need to change the port number to suit your environment.
As soon as you save StudentClient.tt, the proxy class will be created in the StudentClient.cs file. If this is not the case, then right-click on it and choose “Run Custom Tool”.

image

Now that we have a proxy, we can write the code that accesses the service.
Replace the Program class with the following code:

class Program {
    // Get an entire entity set.
    static void ListAllStudents(Default.Container container) {
        foreach (var s in container.Students) {
            Console.WriteLine("{0}, {1}, {2}", s.FirstName, s.LastName, s.Major);
        }
        Console.WriteLine(string.Concat(Enumerable.Repeat("=", 50)));
    }

    static void AddStudent(Default.Container container, Student student) {
        container.AddToStudents(student);
        var serviceResponse = container.SaveChanges();
        foreach (var operationResponse in serviceResponse) {
            Console.WriteLine("Response: {0}\n", operationResponse.StatusCode);
        }
    }

    static void Main(string[] args) {
        // Adjust the following port number to suit your environment.        string serviceUri = "http://localhost:51850/odata/";
        var container = new Default.Container(new Uri(serviceUri));
        ListAllStudents(container);
        int count = container.Students.Count();
        var student = new Student() {
            FirstName = "First " + (count + 1),
            LastName = "Last " + (count + 1),
            Major = "Major " + (count + 1)
        };

        AddStudent(container, student);
        ListAllStudents(container);
        Console.ReadKey();
    }
}


After making sure the Server application is running, run the Client application by right-clicking on the console application and choosing: Debug >> Start new instance

image

You should see the following console window:

image

Note that every time you run the client a new student gets added. The output above shows the list of students before and after a record is added.
I trust this walk-through is useful to you.






Monday, August 19, 2013

Enable “Team Sites” in SharePoint 2013 “Publishing Site”

If you created a site collection based on the publishing site, by default SharePoint 2013 does not show the Team Site template.

To enable the Team Site template:

  1. Site Settings >>  Page Layout and Site Template Settings (under Look and Feel)
  2. Under “Subsite Templates”, add the "Team Site (All)" entry
  3. Save by clicking on the “OK” button

Saturday, April 6, 2013

Tutorial: Simple SignalR Hub with ASP.NET MVC 4

ASP.NET SignalR is a new HTTP technology that allows for a persistent connection between a client and a server. Check out http://signalr.net/ for more information on SignalR.

Here is a tutorial on creating a simple “Chat” SignalR server application using C# and ASP.NET MVC 4 in Visual Studio 2012. The client application will be an ASP.NET MVC View.

  1. Start Visual Studio 2012.
  2. File >> New Project… >> Visual C# >> Web >> ASP.NET MVC 4 Web Application. Name the application “MvcChatSignalR” then click on OK.
  3. Select the Empty template and the Razor view engine. For this example, there is no need to create a unit test project. Click on the OK button.
  4. In the NuGet “Package Manager Console”, type: Install-Package Microsoft.AspNet.SignalR. This will install all the bits necessary for SignalR.
  5. The “readme.txt” file pops up in Visual Studio. You are reminded that the “RouteTable.Routes.MapHubs();” code must be placed inside your Global.asax.cs file. Copy this code and paste it into the “Global.asax.cs” file right after “AreaRegistration.RegisterAllAreas();” as shown below:
    protected void Application_Start() {
    AreaRegistration.RegisterAllAreas();

    RouteTable.Routes.MapHubs();
    WebApiConfig.Register(GlobalConfiguration.Configuration);
    FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
    RouteConfig.RegisterRoutes(RouteTable.Routes);
    }
    The SignalR route must be placed before the MVC route so that the requests for the hub are not swallowed up by the MVC route.



  6. Next, we will create a server-side hub. Create a folder named “Hubs” and in there create a class named “Chat.cs”. The Chat class inherits from the “Hub” base type and implements the server-side logic. Any public method declared in the hub class is callable from SignalR clients. Make sure the “Chat.cs” class file looks like this:
    public class Chat : Hub { 
    public void SendMessage(string nick, string message) {
    Clients.All.PublishMessage(nick, message);
    }
    }
    “PublishMessage” is not defined on the server-side application. This is a dynamic function that will be called in the client’s JavaScript. You can, if you like, annotate the server hub class with another name that the client can use. For example, we can give the server class the name “MessageSender” with annotation [HubName(“MessageSender ”)]. We are not doing this in our simple example.



  7. Since we created an empty MVC 4 project, we do not have a _Layout.cshtml page. Create a folder named “Shared” under Views. Inside the “Shared” folder, add a file named “_Layout.cshtml” with the following content:
    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="utf-8" />
    <title>@ViewBag.Title - My SignalR Chat Hub</title>
    <link href="~/favicon.ico" rel="shortcut icon"
    type="image/x-icon" />
    <link href="~/Content/Site.css" rel="stylesheet" />
    <meta name="viewport" content="width=device-width" />
    </head>
    <body>
    <div id="body">
    <section class="content-wrapper main-content clear-fix">
    @RenderBody()
    </section>
    </div>
    </body>
    </html>



  8. In the “Controllers” folder, add a new controller named “HomeController” using the “Empty MVC controller” template as shown below:
    image
  9. To create a view for the Index action method, right-click on “Index()” and select “Add View…”. This opens up the “Add View” dialog. y1giyb3b
  10. Simply click on the “Add” button without changing anything. This creates a plain file “Index.cshtml” in the in the Views/Home folder.
  11. Replace the code in “Index.cshtml” with the following code:
    <h2>Chat</h2>
    <label for="nick" >Your chat nickname:</label><br />
    <input type="text" name="nick" id="nick" />
    <br /><br />
    <label for="message" >Message:</label><br />
    <input type="text" name="message" id="message" maxlength="100" />
    <div id="chatWindow" style="width: 100%; height: 300px; overflow: scroll; border: 1px solid grey"></div>
    <br />
    <script src="~/Scripts/jquery-1.6.4.min.js"></script>
    <script src="~/Scripts/jquery.signalR-1.0.1.min.js"></script>
    <script type="text/javascript" src="/signalr/hubs"></script>
    <script>
    $(function () {
    // get handle to chat hub generated by SignalR
    var chatHub = $.connection.chat;

    // add method that can be called by the hub to update chat
    chatHub.client.publishMessage = function (nick, msg) {
    var chatWin = $("#chatWindow");
    chatWin.html(chatWin.html() + "<b>" + nick + "</b>: " + msg + "<br />");
    };

    // start the connection with the hub
    $.connection.hub.start();
    $(document).keypress(function (e) {
    if (e.which == 13) {
    // when the 'Enter' key is pressed, send the message to hub
    chatHub.server.sendMessage($("#nick").val(), $("#message").val());
    $("#message").val("");
    }
    });
    });
    </script>



  12. Make sure you adjust the names of the JavaScript files to suit your environment. Also, note that the JavaScript file “/signalr/hubs” is not a physical file on the server. It is dynamically generated by the server
  13. Compile and run the application. Open two different browsers (for example Chrome and IE) that point to the same URL. As you post a message from one browser, it shows up in both browsers. This is the power of SignalRdm2f3ch1

I hope you found this short tutorial useful. At this point, I am sure your mind is spinning with potential applications that you can build with this technology.

Saturday, March 16, 2013

Northwind-mania: CRUD operations against Web API Category table

Web API was introduced together with ASP.NET MVC 4. It is an ideal platform for building RESTful applications. In this tutorial, we will create a simple Web API server application using ASP.NET MVC 4. We will then consume the server application from a simple C# Command Line client application that executes CRUD operations against the Northwind Category table through Web API. The acronym CRUD stand for (C)reate (R)etrieve (U)date (D)elete.

Let us start by creating a Web API server web application using the famed Northwind database Category table.

Building the Web API server application

  • Start Visual Studio 2012
  • File >> New Project >> Visual C# >> Web >> ASP.NET MVC 4 Web Application
  • Name the Application NorthwindWebApi and click on OK
  • On the “Project Template” dialog, select the “Web API” template then click on OK
  • Right-click on the Models folder and choose: Add >> New Item >> ADO.NET Entity Data Model
  • Name the data model NorthwindModel.edmx
  • On the “Entity Data Model Wizard” dialog, select “Generate from database” then click Next
  • Click on “New Connection” and subsequently connect to the Northwind database that you have access to
  • When you are back at the “Entity Data Model Wizard” dialog, change the entity connection setting to NorthwindContext as this becomes the name of our Entity Framework context. Click on Next.
  • Select only the Categories table then click on Finish
  • Build once by hitting Ctrl-Shift-B on your keyboard so that the newly created classes are visible to your Visual Studio environment

Next we need to create a Web API controller for the Categories table. This is done very easily in ASP.NET MVC 4.0.

  • Right-click on the Controllers folder and choose: Add >> Controller
  • Make selections as shown in the dialog below:

image

  • When you are done, click on Add.
  • Have a look at the code in the CategoryController.cs class. You will notice that Visual Studio 2012 has conveniently produced for us all the action methods that cater for Post (Create); Get (Retrieve);  Put (Update); and Delete.

Now let us test to confirm that our Web API controller for categories actually works.

  • Hit Ctrl-F5 in Visual Studio to start your web application and view the home page in a browser.
  • Click on the API link on the top right-hand side. This takes you to the “ASP.NET Web API Help” page that shows you some documentation on how Web API works
  • Scroll down to the Category section. Click on “GET api/Category”. This shows you sample JSON and XML data that gets returned depending on the request header.
  • Click “Back” on the browser to return to the “ASP.NET Web API Help” page
  • In the address line, replace “Help” with api/Category. Your address URL should look similar to: http://localhost:14350/api/Category
  • If you are using IE, you will notice that a *.json file is being downloaded. If you open this .json file in Notepad you will notice that it contains all our categories serialized as JSON objects. We are now ready to build our C# command-line client.

Building the C# command-line Web-API client

  • In Visual Studio 2012 right-click on the solution and choose: Add >> New Project >> Visual C# >> Console Application
  • Name your console application WebApiClient
  • Let us first create a Category class on the client command-line application. This will be used to construct C# objects from de-serialized Category JSON objects. Create the following class:
public class Category {
public int CategoryId { get; set; }
public string CategoryName { get; set; }
public string Description { get; set; }

public override string ToString() {
string str = string.Format("ID={0}; Name={1}; Description={2}", CategoryId, CategoryName, Description);
return str;
}
}
We will need to use a NuGet package named “Microsoft ASP.NET Web API Client Libraries” for accessing Web API through HTTP.


  • Right-click on the command-line project “WebApiClient” and choose: Manage NuGet Packages. Enter “Microsoft ASP.NET Web API Client Libraries” in the search toolbox on the top right-hand side of the dialog. 

  • When the appropriate NuGet package appears, click on the Install button beside it.
image 




  • After the package installs, click Close to close the dialog

  • Add a reference to the “System.Net.Http” assembly

Client-side helper class


The CategoryWebApiHelper class will be used to simulate CRUD operations. In the command-line client application, create a class named CategoryWebApiHelper with the following instance variables and constructor:

public class CategoryWebApiHelper {
private string apiUrl = "";
HttpClient client = new HttpClient();
public CategoryWebApiHelper(string baseUrl, string apiUrl) {
this.apiUrl = apiUrl;
this.client.BaseAddress = new Uri(baseUrl);
// Add an Accept header for JSON format.
this.client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
}
}


  • You will need to resolve the HttpClient and MediaMediaTypeWithQualityHeaderValue classes

The GET helper methods for data retrieval

We will need two get methods. One to retrieve all categories and one to retrieve a specific category by ID. First, add the following Get() method to the CategoryWebApiHelper class that essentially reads in all the categories from the database:
public List<Category> Get() {
HttpResponseMessage response = client.GetAsync(this.apiUrl).Result;
if (response.IsSuccessStatusCode) {
var categories = response.Content.ReadAsAsync<IEnumerable<Category>>().Result;
return categories.ToList();
}
else
return null;
}

Notice that async calls are being made to the server. The most interesting thing about the above code is that the ReadAsAsync method reads the response body and de-serializes it to a specified CLR type.


The HttpResponseMessage has a property IsSuccessStatusCode that indicates whether or not the response is OK.


Next, we will add a method that retrieves data for a Category object specified by the CategoryId.

public Category Get(int customerId) {
HttpResponseMessage response = client.GetAsync(this.apiUrl + customerId).Result;
if (response.IsSuccessStatusCode) {
var category = response.Content.ReadAsAsync<Category>().Result;
return category;
}
else
return null;
}




The POST helper method for data creation


Add the following method to create a Category record in the database:

public string PostInsert(Category category) {
HttpResponseMessage response = client.PostAsJsonAsync(apiUrl, category).Result;
if (response.IsSuccessStatusCode)
return string.Format("Category {0} inserted successfully", category.CategoryName);
else
return string.Format("{0} ({1})", (int)response.StatusCode, response.ReasonPhrase);
}
Unlike with the get methods where we used client.GetAsync(), we use client.PostAsJsonAsync() in order to insert data. Notice that the PostAsJsonAsync() method takes two parameters – namely a relative URL and the Category object.

The PUT helper method for data updates


The helper method for updating category data is shown below:

public string PutUpdate(Category category) {
HttpResponseMessage response = client.PutAsJsonAsync(this.apiUrl + category.CategoryId, category).Result;
if (response.IsSuccessStatusCode)
return string.Format("Category {0} updated successfully", category.CategoryId);
else
return string.Format("{0} ({1})", (int)response.StatusCode, response.ReasonPhrase);
}
The PutAsJsonAsync() method is used to update data. It takes two arguments. The first argument contains information about the CategoryId that is to be updated. The second argument is a Category object.

The DELETE helper method

Finally, the helper method for deleting data needs to know the primary key as shown below:
public string Delete(int categoryId) {
HttpResponseMessage response = client.DeleteAsync(this.apiUrl + categoryId).Result;
if (response.IsSuccessStatusCode)
return string.Format("Category {0} deleted successfully", categoryId);
else
return String.Format("{0} ({1})", (int)response.StatusCode, response.ReasonPhrase);
}
The DeleteAsync() methods needs the CategoryId that is to be deleted.

Testing our Helper methods

In the Main() method of your Program.cs class, construct an instance of the CategoryWebApiHelper class as follows:
CategoryWebApiHelper helper = new CategoryWebApiHelper("http://localhost:14350/", "api/category/");
Adjust the above URL to suit your particular environment. Next, let’s just read all the items in the Categories table. Add the following code to the Main() method:
// get all Category items
List<Category> categories = helper.Get();
foreach (Category t in categories)
Console.WriteLine(t);
Console.WriteLine("============================================");


Run the command-line application by hitting Ctrl-F5 and you should see output similar to:
image 



Next, lets retrieve data for a specific category, say ID=5. Add this code to your main method:

// get one Category
Category category = helper.Get(5);
if (category != null)
Console.WriteLine(category);
Console.WriteLine("============================================");

This will result in output like the following:


image


Similarly, you can test our other helper methods for adding, updating, and deleting data.


Adding data

// Add a Category
var newCategory = new Category() {
CategoryName = "Teas",
Description = "Darjeeling"
};
Console.WriteLine(helper.PostInsert(newCategory));



Updating data

// Update Category with ID=12
Category category = helper.Get(12);
category.Description = "Peppermint";
Console.WriteLine(helper.PutUpdate(category));
Console.WriteLine(helper.Get(12));


Deleting data

// Delete Category with ID=12
helper.Delete(12);

It is strange how it is always easiest to delete.


I hope you found this post useful.

Thursday, November 29, 2012

Synchronizing SharePoint 2010 user profile with AD

There could be scenarios like these:

- an employee changed his or her name
- an employee changed their mobile phone number
- etc …

The profile information in SharePoint is outdated and needs to be refreshed from AD, where the information is more recent.

The powershell command to do this is:

Get-SPUser –Web http://site | Set-SPUser –SyncFromAD

This command cycles through all the SharePoint users and updates the profile. If you come across any errors it is because there are some accounts in SharePoint or on the local server environment that do not exist in SharePoint. If you go into the appropriate SharePoint site you will notice that profiles have been updated.

Thursday, October 18, 2012

SharePoint 2010 Web Part Error: A Web Part or Web Form Control on this page cannot be displayed or imported. You don’t have Add and Customize Pages permissions required to perform this action

 

I deployed  a SharePoint 2010 on a customer’s system. At first, everything worked OK when users with elevated privileges were testing the part. However, soon after read-only users started experiencing the above error. If a user’s privilege was escalated to “Designer”, it would start working again.

The solution to the problem is to find the SharePointProjectItem.spdata file associated with the web-part and change the IsSafeAgainstScript to true in the <SafeControl..> element.

For Example:

<SafeControls>
    <SafeControl Name="SafeControlEntry1"
        Assembly="$SharePoint.Project.AssemblyFullName$"
        Namespace="Medhat.Ca.MyWebpart"
        TypeName="*"
        IsSafe="true"
        IsSafeAgainstScript="true" />
</SafeControls>

The explanation for this error is that users with privileges below "Design” are not allowed to add web-parts into web pages.

Saturday, September 8, 2012

Dual boot Windows 8 from a VHD file under Windows 7

Windows 8 has been available on MSDN for almost a month now. In addition, Windows 8 is now available to students under the Dreamspark program. At the moment, there are many among us who are using Windows 7 as our main operating system on our laptops and desktops. Some of us are willing to explore Windows 8 without necessarily losing our Windows 7 environment. A good way to accomplish this is to install Windows 8 as a VHD instance.

image

The assumption here is that you are installing Windows 8 on a computer that already has Windows 7.

Here are some advantages to using a VHD file to dual boot from:

  1. You can easily backup the VHD drive, thus backing up your entire Windows 8 operating system. It is particularly useful to do a backup of the VHD file right before installing a major piece of software that could potentially mess up your environment.
  2. You can move your VHD file from one computer to another.
  3. It acts exactly as if the Windows 8 operating is installed directly on a separate partition on your hard drive.
  4. You need not go through the pain of creating any additional partition on your hard drive.

Below are the steps you need to follow in order to accomplish this.

Steps for Installing Windows 8 in a VHD drive

  • Create a DVD (or bootable USB) from the ISO image that you obtained with Windows 8 on it.
    • To create a bootable USB from your ISO image, download a free utility from Microsoft at http://tinyurl.com/4qfdm4x.  Here’s what the download looks like:

image

    • To create a bootable DVD from your ISO image, place a blank DVD in the drive and simply double click on the ISO file. Windows 7 has a built-in application named “Windows Disk Image Burner”.

image

Alternatively, you can use any other application that is capable of burning a DVD from an ISO file. I recommend a freely available application named “imgburn” that I use and like.
  • Reboot your computer from the DVD (or USB). This may require you to get into the BIOS settings of your computer in order to rearrange the boot sequence of your various storage devices.

image

  • At the “Install Windows 8” screen, hit the Shift-F10 keys to open a command prompt.
  • When at the command prompt, type "diskpart <enter>". Wait until you see the command prompt “DISKPART >”.
  • In order to see a list of all available volumes, type "list volume <enter>". Identify the drive name that has ample available disk space which you want to install the VHD into. The drive letter will be under the column entitled “Ltr”.
  • In this example, we will create the VHD file on drive D:. Make sure to replace D: with the appropriate drive letter that fits your situation. You can create either a fixed or dynamic VHD file:
    • Creating a fixed VHD file: A fixed VHD file will allocate the entire maximum size that you set, regardless of whether or not the operating system uses that much space. Note that once you set a size, you cannot increase it in future, so make sure you are reasonably generous in choosing a maximum size. The following command assumes that you will be allocating a fixed VHD drive of 40GB (1GB = 1024 MB):
    • create vdisk file=D:\win8.vhd maximum=40960

      Note: In the command above, substitute D: with the drive letter that suits your situation. You can use any other name you like instead of win8.
    • Creating a dynamic expandable VHD file: A dynamic VHD file will initially be as large as the data used by the VHD. This can grow to the maximum size set when you create the VHD file. In the example below I will create a dynamic VHD drive that can grow to a maximum size of 40GB:
    • create vdisk file=D:\win8.vhd maximum=40960 type=expandable

  • Wait until the VHD drive has been 100% created. Next we need to select the VHD that was created. This is done by entering a command similar to the one below, depending on the drive letter and VHD file name you used:
  • select vdisk file=D:\win8.vhd
  • The next step is to attach to the VHD file. This is done with the the command:
  • attach vdisk
  • At this point we have done all that is necessary to create a VHD file and attach to it. We can now exit the DISKPART prompt. To do so, enter the following command:
  • exit

  • Close the command prompt window by clicking on the X located on the top-right-hand side of the window. We can now continue with the regular Windows 8 install.
  • Click “Next” on the “Windows Setup” dialog.

image

  • Click on the “Install Now” button on the next dialog.
  • The next dialog will ask you for your product key. Enter your product key and click “Next”.
  • Accept the license terms on the next dialog by clicking on the “I accept the license terms” checkbox then click on the “Next” button.
  • The next dialog will enable you to choose whether you want to do an upgrade or custom install. Since we want to install Windows 8 from scratch, we will choose the second option “Custom: Install Windows only (advanced)” by clicking on it.
  • The next window is very critical because it is at this point that you select the drive that will hold the new operating system. The primary manner by which you can identify this drive is by the size of the drive (I.E. in the case of this example it is 40GB) and the fact that it is still “Unallocated Space”.
    • Note that you run the risk of losing data if you choose the wrong drive.
    • Ignore the message “Windows can’t be installed on this drive. (Show details)

    Select the correct drive then click “Next”.

  • The rest is should proceed smoothly. When the installation is finished, Windows 8 will be set as the default operating system. You will, however, be given the option to boot into Windows 7 if you so desire.

Steps for removing the Windows 8 VHD

  • Boot into Windows 7
  • Find the Windows 8 VHD file on your hard drive
  • Delete the Windows 8 VHD file
  • Reboot the computer

Hope this is useful to you.

References:

Tutorial: Windows 8 VHD - Create at Boot to Dual Boot with