Configuring and Deploying an MVC4 application as a Cloud Service with Azure SQL and Storage
Go to Azure Management Portal. Enter credentials.
Create a new cloud service. Provide a name for your application.
Create a SQL database. Provide a name of your DB.
Enter database credentials.
Create a new Storage account. Provide a name for Storage account.
Next, configure the firewall for your new server to allow connections through. Click Servers at the top of the page. Click on the server you just created so that you see a white arrow to the right. Click on the arrow to open the server page.
On the server page, click Configure to open the firewall configuration settings and specify the rule as follows:
Copy the current client IP address. This is the IP address that your router or proxy server is listening on. SQL Database detects the IP address used by the current connection so that you can create a firewall rule to accept connection requests from this device.
Paste the IP address into both the beginning and end range. Later, if you encounter connection errors indicating that the range is too narrow, you can edit this rule to widen the range.
Enter a name for the firewall rule. Click the checkmark to save the rule.
Click Save at the bottom of the page to complete the step. If you do not see Save, refresh the browser page.
Important: In addition to configuring the SQL Database server-side firewall, you must also configure your client-side environment to allow outbound TCP connections over TCP port 1433. For more information, see Security Guidelines for SQL Database.
Before going back to Visual Studio, you need to get the fully-qualified name of your server. The fully qualified domain name of the server uses the following format:
<ServerName>.database.windows.net
Where <ServerName> identifies the server. Write down the server name;
Select the newly created database and click on "show connection strings". Keep a note of connection string.
Modify web project web.config file to point to Azure database using the connection string noted earlier.
<connectionStrings>
<!– Azure SQL Account–>
<add name="<YourDBContext>" connectionString="data source=<datasource>;Initial Catalog=<initialcatalog>;User ID=<userid>;Password=<password>;Encrypt=true;Trusted_Connection=false;MultipleActiveResultSets=True" providerName="System.Data.SqlClient" />
Deploy the application to Windows Azure
Log back in to Azure account, and download a Windows Azure publishing profile. The publishing profile authorizes your machine to publish packages to Windows Azure using Visual Studio.
Right click on Azure project and click Publish.
Enter your account credentials. A profile will be generated. Save it to your machine.
In the Profile tab of the Publish Web wizard, click Import.
Select the .publishsettings file you downloaded earlier, and then click Open.
Press Next. Specify settings as below.
Enable Code First Migrations and Update the database:
The next task is to enable the Code First Migrations feature in order to create the database based on the data model you created.
In the Tools menu, select Library Package Manager and then Package Manager Console.
In the Package Manager Console window, enter the following commands:
enable-migrations
add-migration Initial
update-database
The enable-migrations command creates a Migrations folder and a Configuration class that the Entity Framework uses to control database updates.
The add-migration Initial command generates a class named Initial that creates the database. You can see the new class files in Solution Explorer.
In the Initial class, the Up method creates the script to create tables and data, and the Down method (used when you want to return to the previous state) drops it.
Finally, update-database runs this first migration which creates the database.
Congratulations! You have now successfully configured and published an MVC 4 EF(Entity Framework) Code First application as a Cloud service with Azure SQL and Storage.
Integration Futures. BizTalk and Windows Azure provide options today and tomorrow.
My company, MPS Partners, and the people on our integration team have been implementing BizTalk Server for well over 10 years. The product has truly come a long way from the days of designing artifacts in Visio. I personally started working with the product when BizTalk Server 2004 was released and have seen the product progress greatly from there. I’ve worked with a lot of BizTalk developers that were great at architecting and implementing integration solutions and some that just couldn’t “get it”. I’ve had clients that were amazed at the types of solutions we could build, some that refuse to use BizTalk because of things they heard, and some that have asked me what that server in their datacenter does (all they know is its called BizTalk and they haven’t had to touch it for several years). Integration is one of the most important workloads for an organization. Integration helps bring companies together and let’s user enter data once and only once. It’s not a glorious workload, it’s behind the scenes and gets very little praise. It does get all the blame when it’s not working for any time at all.
There is a reason that integration takes a certain type of person and organization to get right, especially the first time. Integration involves a new problem every day. Systems are different and integration is hard. From a business standpoint, even getting requirements correct from two parts of an organization speaking totally different business languages is an art unto itself. Technically we are transforming data structures from one system to completely different structures in one or many destination systems. It takes a unique approach, a lot of flexibility, and one more thing to be successful: Options.
Options. That’s our secret sauce to integration. We have a really big toolbox with may different tools that help us get our job done. (OK. We also need a mission-critical, scalable platform for reliable messaging, but in another blog I can explain why BizTalk and Windows Azure give us the best solution here). It is about having a myriad of tools and architectural patterns to solve that days integration problem. There is a small cost. Options require choices. Good, well planned out choices that balance things like supportability, scalability, and time to market. With proper governance, proper planning, and consistency of implementation, the options give us what we need and the choices we make determine our success. Without that governance, planning, consistency, and good choices, an organization is destined to fail.. and many have.
Microsoft with BizTalk Server, and the great community that supports it, have always given us those options. Given those options, here are just a few choices we make:
- Point-to-Point vs. Pub/Sub

- Pipeline components vs. Maps
- Maps vs. XSLT
- Itineraries vs. Orchestrations
- Custom Adapter vs. Helper components
- Adapters vs. Web Services
- Deployment Binding vs. Direct Binding
- BizTalk BRE vs. 3rd party BRE or custom code
- Real-time BAM vs. Traditional ETL
The Microsoft application integration platform has always given us enough options to create successful solutions for our customers. Where the product has been just a little behind, the community has often stepped up to provide event more options. MPS Partners has been successful since its inception leveraging this large toolbox to provide our customers value.
The BizTalk 2010 R2 CTP just became available. Guess where? Windows Azure. Before the public can even download the bits, Microsoft has given us access to the CTP as a virtual machine in Windows Azure. Think about that. How many times in a B2B/EDI solution are we trying to push BizTalk out to the perimeter of the network to get closer to our trading partners? It usually is a struggle as we have internal integration workloads we want well within the firewall and its expensive to maintain two integration environments. Now we can quickly spin up an integration platform in the Microsoft cloud. A very nice new option for our customer.![]()
If you’ve been paying attention, there is another integration option coming. Microsoft is providing a PaaS option in Windows Azure for EAI/EDI workloads. I have an example of an EAI process to the left. When this becomes fully available, we can push that B2B workload on to a fabric that Microsoft provides. The concept of a “server” is gone. We give the developed artifacts to Microsoft and they are responsible for making sure our integration workload is available and scalable. They also give us tools to integrate back on premise with the Windows Azure service bus.
If you have been doing integration as long as I have, you know that these options just give us more ways to solve problems for our customers. Some analysts recently have claimed that this shows weakness in Microsoft’s integration roadmap and hinted that these new options will usurp the older options like BizTalk Server. I totally disagree. In fact Microsoft has more vision in this space than any of their competitors. Microsoft is giving us more and more options on premise and in the cloud to help our customers now and in the future. Do these options make our decision making harder? Yes, but the available options allow us to create the right solution for every one of our clients.
Integration Futures. BizTalk and Windows Azure provide options today and tomorrow.
My company, MPS Partners, and the people on our integration team have been implementing BizTalk Server for well over 10 years. The product has truly come a long way from the days of designing artifacts in Visio. I personally started working with the product when BizTalk Server 2004 was released and have seen the product progress greatly from there. I’ve worked with a lot of BizTalk developers that were great at architecting and implementing integration solutions and some that just couldn’t “get it”. I’ve had clients that were amazed at the types of solutions we could build, some that refuse to use BizTalk because of things they heard, and some that have asked me what that server in their datacenter does (all they know is its called BizTalk and they haven’t had to touch it for several years). Integration is one of the most important workloads for an organization. Integration helps bring companies together and let’s user enter data once and only once. It’s not a glorious workload, it’s behind the scenes and gets very little praise. It does get all the blame when it’s not working for any time at all.
There is a reason that integration takes a certain type of person and organization to get right, especially the first time. Integration involves a new problem every day. Systems are different and integration is hard. From a business standpoint, even getting requirements correct from two parts of an organization speaking totally different business languages is an art unto itself. Technically we are transforming data structures from one system to completely different structures in one or many destination systems. It takes a unique approach, a lot of flexibility, and one more thing to be successful: Options.
Options. That’s our secret sauce to integration. We have a really big toolbox with may different tools that help us get our job done. (OK. We also need a mission-critical, scalable platform for reliable messaging, but in another blog I can explain why BizTalk and Windows Azure give us the best solution here). It is about having a myriad of tools and architectural patterns to solve that days integration problem. There is a small cost. Options require choices. Good, well planned out choices that balance things like supportability, scalability, and time to market. With proper governance, proper planning, and consistency of implementation, the options give us what we need and the choices we make determine our success. Without that governance, planning, consistency, and good choices, an organization is destined to fail.. and many have.
Microsoft with BizTalk Server, and the great community that supports it, have always given us those options. Given those options, here are just a few choices we make:
- Point-to-Point vs. Pub/Sub

- Pipeline components vs. Maps
- Maps vs. XSLT
- Itineraries vs. Orchestrations
- Custom Adapter vs. Helper components
- Adapters vs. Web Services
- Deployment Binding vs. Direct Binding
- BizTalk BRE vs. 3rd party BRE or custom code
- Real-time BAM vs. Traditional ETL
The Microsoft application integration platform has always given us enough options to create successful solutions for our customers. Where the product has been just a little behind, the community has often stepped up to provide event more options. MPS Partners has been successful since its inception leveraging this large toolbox to provide our customers value.
The BizTalk 2010 R2 CTP just became available. Guess where? Windows Azure. Before the public can even download the bits, Microsoft has given us access to the CTP as a virtual machine in Windows Azure. Think about that. How many times in a B2B/EDI solution are we trying to push BizTalk out to the perimeter of the network to get closer to our trading partners? It usually is a struggle as we have internal integration workloads we want well within the firewall and its expensive to maintain two integration environments. Now we can quickly spin up an integration platform in the Microsoft cloud. A very nice new option for our customer.![]()
If you’ve been paying attention, there is another integration option coming. Microsoft is providing a PaaS option in Windows Azure for EAI/EDI workloads. I have an example of an EAI process to the left. When this becomes fully available, we can push that B2B workload on to a fabric that Microsoft provides. The concept of a “server” is gone. We give the developed artifacts to Microsoft and they are responsible for making sure our integration workload is available and scalable. They also give us tools to integrate back on premise with the Windows Azure service bus.
If you have been doing integration as long as I have, you know that these options just give us more ways to solve problems for our customers. Some analysts recently have claimed that this shows weakness in Microsoft’s integration roadmap and hinted that these new options will usurp the older options like BizTalk Server. I totally disagree. In fact Microsoft has more vision in this space than any of their competitors. Microsoft is giving us more and more options on premise and in the cloud to help our customers now and in the future. Do these options make our decision making harder? Yes, but the available options allow us to create the right solution for every one of our clients.
BizTalk as IaaS
Microsoft recently
announced CTP Release for BizTalk 2010 R2 ( http://blogs.msdn.com/b/biztalk_server_team_blog/archive/2012/08/29/announcing-microsoft-biztalk-server-2010-r2-ctp-release.aspx ).
At this point CTP is
available only to TAP customers, but they have made CTP available for preview
to all customer as Virtual machine pre-defined image on Azure. We will look into how quick ( it is in
minutes ) and easy ( very simple wizard based step by step process ) it is to
setup a new Biztalk environment reducing the lead-time and leveraging power of
Cloud.
Let’s get started!
- Login to Azure management
Portal ( https://manage.windowsazure.com/ ) with your Live loginId (
signup for Azure Trial offer ). As
soon as you login you will see a newly created portal

Before you can see
the Virtual Machine and other new Cloud based services, you will need to
sign-up for those @
https://account.windowsazure.com/PreviewFeatures?wa=wsignin1.0

Once you have signed
up, you can log back into Azure management portal and you should see now
Virtual Machine into list of Items available.
Click on Create an Item.
From Pop-up menu
select Virtual machine

Click on From
Gallery

From the VM OS
Selection, select Microsoft BizTalk Server 2010 R2 CTP ( There are options
available currently for creating VM for SQL Server 2012, Windows Server 2008 R2
Sp1, Windows Server 2012 and Linux, Ubuntu )

Click Next and you
will be presented with VM Configuration.
Enter your virtual machine name and enter your password along with Size ( For
BizTalk 2010 I selected Medium Size )

Moving on to next
page in wizard, will provide selection on VM Mode. We will select standalone virtual machine as
we are creating a new VM. Enter your DNS name which will be verified on
availability
We will keep default
storage account to automatically generate storage account, with default Region
as West US

Last Page will
prompt for selecting availability sets ( Availability sets is the group of VM
deployed across multiple physical locations ).
This applies to the scenario when we are connecting VM to other VM. Since we are not connecting to other VM, we
will leave it as "None"

Click Complete and
it will start provisioning the VM


After few minutes,
you will see an VM creates successfully.
To connect to successfully created VM, select Connect from the command
bar on the bottom of portal

It will
create/download/open RDP file for the VM that we created ( *.cloudapp.net ).
Connect to VM remotely and we should get same experience as if connecting to
virtual machine created locally on the network.
Upon logging into
image, it will have all pre-requisite installed ( BizTalk 2010 R2 and SQL
Server 2012 ). The VM also comes with
Visual Studio 2012 RC. At the first
login, it will execute the start up script to complete SQL installation as well
as setup IIS and DTC Configuration ( neat!! ).
At this point we should be able to configure the BizTalk Server 2010 R2
as we do for regular BizTalk Installations.





Wohoo!! An VM with
BizTalk 2010 R2 up and running in < half hour
Entity Framework Code First Approach Using SQL Express
In one of the recent projects, I had a task of putting together an architecture for an MVC 4 web application that is hosted on cloud using Windows Azure as the platform. One of the challenges was to select an approach on how to use Entity Framework (EF). After I played with EF-Code First approach I fell in love with it as I really like the idea of convention over configuration and that you can automatically create and generate the schema directly from the model (POCO) classes. No need to create your tables and stored procs before you start writing your .NET code, as EF does all the work for you.
The purpose of this blog is not to show details on how to use EF-Code First approach as there are tons of excellent resources on the topic. What I would like to focus on is how to use the approach with SQL Express as most examples on the web currently use SQL CE (compact edition).
Here are the high level steps on how to setup EF Code First with SQL Express.
Step 1: Create you model classes. For example
public class Product
{
public int ProductId { get; set; }
public string Name { get; set; }
public string Description { get; set; }
}
Step 2: Create a class to handle the retrieval/persistence of model instances from a database. Lets call it ProductContext”. It need to derive from the DbContext base class.
public class ProductContext : DbContext
{
public DbSet<Product> Products { get; set; }
}
Step 3: Modify the web.config to setup a connection-string to point to a SQL Express database. When you create a DbContext class with EF code-first,it needs a matching connection string . In this example, we named our context class “ProductContext”, so the name of our connection string need to be “ProductContext” as well.
<connectionStrings>
<add name="ProductContext" providerName="System.Data.SqlClient" connectionString="Data Source=.\SQLEXPRESS;Initial Catalog=ProductDb;Integrated Security=SSPI;User Instance=true;MultipleActiveResultSets=True"/>
</connectionStrings>
After you compile your application, your SQL Express database will be created by Entity Framework. If you try to connect to your new database through SQL Server Management Studio, you will be surprised not to find your database. So where is my new DB located? A quick search on my machine revealed that the SQL Server database file was created at the following location:
C:\Users\<UserName>\AppData\Local\Microsoft\Microsoft SQL Server Data\SQLEXPRESS\ProductDb.mdb
So how do I view the data stored in this mdb file. The best solution I have found is to add a new data connection using Visual Studio “Server Explorer” window.
Select the local machine where your SQL Express is located and select the option of “Attach a database file” pointing to the location of your mdb file.
Now you will be able to see the database created by EF. If you make any changes to your underlying model and recompile your MVC app, you will get access violation error regarding mdb file. You have to make sure to close the active connection by selecting “Close Connection” in Server Explorer.
Once the connection is closed, you should be able to successfully compile the app.
What’s new in ASP.NET MVC 4 at CNUG July 18th, 2012
It was a pleasure to present the exciting new features in ASP.NET MVC 4 RC, thanks to the great audience and Keith Franklin.
The Slides and the Demo solution can be downloaded from below.
Feel free to reach out in case of any questions.
SharePoint 2010: Custom Global Navigation – Implementation (3 of 3)
Overview
Design Review
- Global Navigation needed to be implemented in multiple web applications, each running under a dedicated application pool service account
- Personalized Global Navigation needed to be displayed for every user of the site regardless of permissions, this included:
- Farm Admins
- Site Collection Admins
- Site Contributors
- Anonymous Users
- The security of the farm needed to be configured so that the code could query the various sites regardless of where the site exists (what Web Application, Site Collection, etc.)
Farm Topology
- Collaboration Web Application
- Test Community A Site Collection
- Test Community B Site Collection
- Internal Projects Site Collection
- Internal Project 1 Site
- Internal Project 2 Site
- Customer Projects Site Collection
- Project 3 Site
- Project 4 Site
Configure Permissions
Add service accounts to the local administrators group on each WFE
Configure service accounts in the User Policy of the Collaboration Web Application
- Zones: (All Zones)
- Permissions: Full Control
- Account operates as System
Map the db_owner permission on each content database for each service account
- Verify that each of the service accounts are configured under security (this should be the default but it’s always best to double check)
- Go to properties for the login and modify user mappings
- For each content database used by the collaboration web application make the login as the db_owner.
Testing
- Test that the Global Navigation appears properly in the Site that is hosting the Global Navigation List (in our scenario this was in a web application separate from the collaboration web application)
- Test that the Global Navigation appears properly from a community or project site within the collaboration web application
- Test that the Global Navigation appears properly in a web application separate from the previous tests (a separate records center web application in our environment)
- Test with a couple different user accounts to make sure users are only seeing communities/projects that they are authorized to collaborate on
Final Thoughts
Windows 8 Release Preview–Why Microsoft Will Become a Tablet Leader
This past week, I upgraded my Samsung Series 7 Slate to the Windows 8 Release Preview. I have been looking forward to the preview since I started using the Consumer Preview earlier in the year. Microsoft has asserted that the Release Preview is now feature complete. Here are a few things that I’ve noticed:
- The Metro UI is now highly responsive. The experience of touching, swiping and pinching is very predictable similar to the experience on an iPad.
- Metro is a radical departure from the traditional Windows 7/XP desktop. It’s hard to argue that fact. However, My experience is that it is highly intuitive. Tapping on a tile gets you to the app. A swipe from left to right switches between apps and a swipe from right to left brings you back to the start page.
- The real beauty of Metro however, is the apps themselves. With the Release Preview Microsoft has release a series of apps in its store. The Sports and Finance apps are great examples of how content can be displayed in a simple to view and easily understandable fashion. Metro allows developers to hide navigation and then make it available with a simple upwards swipe. In addition, unlike the iPad, well built Metro apps share a common appearance and navigation structure that creates a truly common experience.
- The Xbox Companion App working together with my Xbox gives a nice glimpse into how Microsoft intends to share the Metro experience not only across apps but across devices. With the Xbox App, I can control what’s on my TV screen from my tablet.
- The keyboard (which was “quirky” with the Consumer Preview) is very intuitive and easy to use with the Release Preview. The keys are large and responsive making the tablet into a great web browsing experience with IE10
- The Store is a very intuitive UI for searching for apps and downloading them. Apps are grouped into logical departments that make it easy to find items of interest. Once you’ve selected an app for download, they download very quickly over a standard wireless connection.
- The boot time in Windows 8 is extremely fast. It takes a few seconds to go from hibernated to on. The experience on my Windows 8 tablet (which is running an Intel 64-bit processor) is similar to the experience with an iPad. Microsoft has not yet publicly shown an ARM device, but my assumption is that it will start up even faster.
I have been taking my Windows 8 tablet into all of my client meetings. I am an avid note taker and for years have been using OneNote with on a Tablet PC with a stylus to take hand written notes. With Windows 8, OneNote is now truly a killer app. I have an tile for OneNote in the first group on my Start Screen. This allows me to begin note taking within seconds. Unlike an iPad, I can use a stylus to “ink” my notes. I have OneNote stored in a SkyDrive, which allows me to sync my notes across all of my devices (including my iPad). This is a huge productivity boost for me. It allows me to leave the laptop at home and focus on my client when in front of them.
I believe Microsoft has a hit on its hands with Windows 8. This WILL NOT be another Vista as some are saying. As with any major OS upgrade, users will have to “un-learn” what they may have known in the past. In that regard Microsoft is taking a page out of Apple’s playbook since Apple regularly cuts ties to its past devices and OSs when it releases a new product.
SharePoint 2010: Custom Global Navigation – UI Implementation & CSS
JJ Bussert has written a blog series that explains the desi
gn, coding, and implementation of the Global Navigation solution. Once the code is written the global navigation control needed to be styled and added to the Master Page.
4. CSS & UI Implementation
Rich Text AreaToolbarBold (Ctrl / Alt + Shift + B)Italic (Ctrl / Alt + Shift + I)Strikethrough (Alt + Shift + D)Unordered list (Alt + Shift + U)Ordered list (Alt + Shift + O)Blockquote (Alt + Shift + Q)Align Left (Alt + Shift + L)Align Center (Alt + Shift + C)Align Right (Alt + Shift + R)Insert/edit link (Alt + Shift + A)Unlink (Alt + Shift + S)Insert More Tag (Alt + Shift + T)Toggle spellchecker (Alt + Shift + N)▼
Toggle fullscreen mode (Alt + Shift + G)Show/Hide Kitchen Sink (Alt + Shift + Z)
FormatFormat▼
UnderlineAlign Full (Alt + Shift + J)Select text color▼
Paste as Plain TextPaste from WordRemove formattingInsert custom characterOutdentIndentUndo (Ctrl + Z)Redo (Ctrl + Y)Help (Alt + Shift + H)
JJ Bussert has written a blog series that explains the design, coding, and implementation of the Global Navigation solution. Once the code is written the global navigation control needed to be styled and added to the Master Page.
1. Design – see JJ’s post here
2. Code – see JJ’s post here
3. Implementation – watch JJ’s blog for this post here
4. CSS & UI Implementation
This blog will walk through the styling and the addition of the control to the master page. This blog assumes that the global navigation code has been implemented. The code discussed here can be included in the same solution (.wsp) as the global navigation or separately, the solution will work either way.
Adding the control to the master page
In order to add the control, you must deploy a custom .master file to the farm and apply it. This solution can still utilize themes if necessary, the solution as discussed does not utilize themes. The navigation that is standard in a SharePoint v4 master page will be removed. That means that any modifications to the OOB Global Navigation settings will not take into effect. These settings can be found in the site settings, under the Look and Feel Section Header, then Navigation and require that the Publishing Features are activated.
First, let’s add a reference to the global navigation user control to the master page. Add the following register line below above the doc type declaration in the master page.
Next, let’s find the current navigation control for the master page.
· There is a div with the ID “s4-topheader2” and the class “s4-pr s4-notdlg” , remove this div from opening to closing tag, there are other elements included in between this div that should be included in the removal.
· There are two placeholders that also need to be hidden, but cannot safely be removed from the page, the IDs are “PlaceHolderHorizontalNav” and “PlaceHolderTopNavBar”. Add the attribute visible=”false” to both placeholders.
Next, let’s add our new control to the master page in the same location so that it will appear on the page. We already have it registered so now we just need an instance of the control. Add the below line above the placeholder with the ID “PlaceHolderTopNavBar”.
Styling the control with CSS
We now have the control on the master page, but it just looks like a bulleted paragraph list and that is not going to work for a navigation solution! There are a number of ways to implement a multi-tiered drop down list, this solution only utilizes CSS and is functional in all browsers.
You can download the CSS here. The styles can be added to any existing CSS file or referenced in the master page or user control independently.
Path:
SharePoint 2010: Custom Global Navigation – Code (2 of 3)
- Design
- Code
- Implementation (Future Topic)
Overview
In Part 1 I discussed the design of the Global Navigation that I recently implemented. It may not be applicable for every situation but it worked well for that particular project. This time I will go into some code snippets of how I queried the object model for the site collections and sites that the current user was authorized to.
Design Review
A quick review of the design and some elaboration on it as we proceed. Note that for this post I will be focusing on the dynamic menu elements because those are the most interesting from a code standpoint. The menu will have two dynamic top level menu items:
- Projects
- Communities
This post will focus on the Communities and Project menus because those are dynamic. Also I will not be going through every line of code from this project, I pulled out snippets of some of the more interesting bits and I rewrote those to make sense when pulled out of context.
Farm Topology
As everyone hopefully knows a SharePoint farm is broken down into Web Applications, Site Collections, and Sites. The project architect decided that the topology will be as follows:
- Collaboration Web Application
- Test Community A Site Collection
- Test Community B Site Collection
- Internal Projects Site Collection
- Internal Project 1 Site
- Internal Project 2 Site
- Customer Projects Site Collection
- Project 3 Site
- Project 4 Site
Querying Sites under a Site Collection
In my example to get a list of Project sites (Internal or Customer) required querying for all Sites within a Site Collection.
struct TempMenuData
{
public string Title;
public string Url;
public DateTime Created;
}
....
SPSecurity.RunWithElevatedPrivileges(delegate {
// Temp storage
var tempList = new List();
/*
* Note: creating the SPSite with SPUserToken.SystemAccount is required even though
* this block is being run as a delegate within RunWithElevatedPrivileges.
*
* This is contrary to what the API doc implies, removing this will cause the * sub.DoesUserHavePermissions() to error with an authorization exception
*/
using (SPSite siteCollection = new SPSite(siteUrl, SPUserToken.SystemAccount))
{
using (SPWeb rootWeb = siteCollection.OpenWeb())
{
// retrieve only Sub-sites that current user is a member of
foreach (SPWeb site in rootWeb.Webs)
{
if ( site.DoesUserHavePermissions( currentUserLogin, SPBasePermissions.ViewPages | SPBasePermissions.ViewFormPages | SPBasePermissions.ViewListItems))
{
tempList.Add(
new TempMenuData
{
Title = site.Title,
Created = site.Created,
Url = site.Url
}
}
}
}
}
IOrderedEnumerable orderedQuery = tempList
.OrderByDescending(o => o.Created)
.OrderBy(o => o.Title);
}
There is a lot going on here and formatting the code to fit in the blog is not necessarily the best way to view the code but I'll break it down.
- Start by running everything in a RunWithElevatedPrivileges delegate
- Open up the SPSite using the SPUserToken.SystemAccount token
- Open up and iterate through each SPWeb within this SPSite
- For each site that is found verify that the current user has sufficient privileges to view the site using DoesUserHavePermissions()
- The various SPBasePermissions are the exact permissions the user must have to be considered authorized to have this site in their global navigation
- The temporary list of menu data is then sorted into a IOrderedEnumerable which is used later to actually generate the menu
Most noteworthy topic is that both RunWithElevatedPrivileges and SPUserToken.SystemAccount are required to properly search the farm. This is because the menu could be called by any user (anonymous, domain user, site admin, farm admin), in my testing the only way to ensure the code worked regardless of the user was to use both techniques. This was confusing enough that I included a block comment reiterating this so no one ever forgot why this was done that way.
Querying Site Collections with a Web Application
The other example involves extracting the list of Communities out of the Collaboration web application.
struct TempMenuData
{
public string Title;
public string Url;
public DateTime Created;
}
....
SPSecurity.RunWithElevatedPrivileges(delegate
{
string subQueryPath = "/communities/";
// Temp storage
var tempList = new List();
SPWebApplication webApp = SPWebApplication.Lookup(new Uri(webAppUrl));
foreach (SPSite s in webApp.Sites)
{
/*
* Note: creating the SPSite with SPUserToken.SystemAccount is required even though
* this block is being run as a delegate within RunWithElevatedPrivileges. Since the
* SPUserToken can not be specified in the SPWebApplication declaration or following
* webApp.Sites call a new SPSite must be instantiated so the proper Token can be
* provided.
*
* This is contrary to what the API doc implies, removing this will cause the
* RootWeb.DoesUserHavePermissions() to error with an authorization exception
*/
using (SPSite s_sys = new SPSite(s.Url, SPUserToken.SystemAccount))
{
if (
s_sys.RootWeb.Url.Contains(subQueryPath) &&
s_sys.RootWeb.DoesUserHavePermissions( currentUser.LoginName, SPBasePermissions.ViewPages | SPBasePermissions.ViewFormPages | SPBasePermissions.ViewListItems))
{
tempList.Add(
new TempMenuData
{
Title = s_sys.RootWeb.Title,
Created = s_sys.RootWeb.Created,
Url = s_sys.RootWeb.Url
});
}
}
}
orderedQuery = tempList .OrderByDescending(o => o.Created) .OrderBy(o => o.Title);
}
This code is very similar to the other snippet
- Start by running everything in a RunWithElevatedPrivileges delegate
- Create a subQueryPath variable – This is the managed path for community site collections
- Create up the SPWebApplication to be queried
- For each SPSite in this SPWebApplication reference that site using the SPUserToken.SystemAccount
- Check that this SPSite
- Is using the specified managed path
- That the current user is authorized to this site
- The temporary list of menu data is then sorted into a IOrderedEnumerable which is used later to actually generate the menu
Again you will notice the logic of this snippet is very similar to the other, there are some notable differences however. First is that the SPSite needs to first be found within the SPWebApplication, then this SPSite needs to be re-created with the SPUserToken.SystemAccount, this is because the SPWebApplication API did not have a way of providing the user token directly. This is an indirect way of accomplishing this but it was the only way I could find.
The other note is that we needed to provide what I called the "subQueryPath", this was my way of filtering what site collections were included in this menu. That was required because if you look at the topology the collaboration web application included community and project site collections, however the menu needed them broken out. Since these different type of collections were using different managed paths I simply check the url of the site to make sure it included "/communities/" (ie. the managed path) before attempting to include it in the menu. This is hard coded in the above snippet but the actual code is more dynamic because this is obviously a bad practice to hard code a value such as this.
Final Thoughts on Code
There were some specific security techniques that were required to ensure that any user would be able to get their personalized menu correctly. This is very tightly related to the next topic that I'm calling "Implementation" because the farm needs some specific configurations so that the above code can do it's thing. The security was the biggest challenge for this project because figuring everything out involved debugging the development server environment and pouring through ULS and Event Log entries. Save yourself some agony and check out all three parts of this blog to see how I set everything up.









CNUG.MVC4RC.zip