Friday, June 27, 2014

Changing the Logo in a SharePoint 2013 Site

If you want to change the default SharePoint 2013 Logo in a brand new SharePoint 2013 Site or Site Collection, it is actually rather easy!!


  1. Click on Site Settings
  2. Under the Look and Feel section, click on Title, description and logo
  3. Specify a Url path to the new Logo (I would HIGHLY RECOMMEND using a relative path to the SiteAssets folder)


Permission Levels in SharePoint 2013

If you want to look at the various Permission Levels in SharePoint 2013 and see what rights/privileges have been assigned to the various built-in SharePoint Permission Groups, it is not exactly intuitive to find where this is located in SharePoint.


  1. Go into Site Settings
  2. Click on Site Permissions
  3. In the Ribbon, click on Permission Levels



Below is the Permission Levels and their corresponding privileges:

  • Full control - Has full control
  • Design - Can view, add, update, delete, approve, and customize
  • Edit - Can add, edit and delete lists; can view, add, update and delete list items and documents
  • Contribute - Can view, add, update, and delete list items and documents
  • Read - Can view pages and list items and download documents
  • Limited Access - Can view specific lists, document libraries, list items, folders, or documents when given permissions
  • Approve - Can edit and approve pages, list items, and documents
  • Manage Hierarchy - Can create sites and edit pages, list items, and documents
  • Restricted Read - Can view pages and documents, but cannot view historical versions or user permissions
  • Restricted Interfaces for Translation - Can open lists and folders, and use remote interfaces
  • View Only - Can view pages, list items, and documents.  Document types with server-side file handlers can be viewed in the browser but not downloaded.

Deleting a SharePoint List using PowerShell

I recently encountered an issue whereby a SharePoint List was restored to a site using a Granular Backup, however, the site could not be deleted from the User Interface.

Of course, I decided to try deleting it via PowerShell using the following script:
$siteUrl = "http://sp2013sp1"
$listTitle = "My List"
 
$web = Get-SPWeb $siteUrl
$list = $web.Lists[$listTitle]
$list.AllowDeletion = $true
$list.Update()
 
$list.Delete()
$web.Close()

As you can guess, the PowerShell script worked!

Thursday, June 26, 2014

Head First Design Patterns Code Download

If you are looking for code downloads for the Head First Design Patterns book, you can find them here: http://www.headfirstlabs.com/books/hfdp/

In addition to downloading the Java code samples, you can even download code samples in C#!
http://www.msquaredweb.com/DesignPatterns/HeadFirstDesignPatternsInCSharp.zip

Wednesday, June 25, 2014

The Observer/Publish-Subscribe Pattern in C#

The Observer Pattern is most commonly known also as the Publish/Subscribe Pattern.

The definition of the Observer Pattern is as follows:

The Observer Pattern defines a one-to-many dependency between objects so that when one object changes state, all of its dependents are notified and updated automatically (Head First Design Patterns-the observer pattern).

Below is the corresponding code in C# for the Observer pattern found in the Head First Design Patterns book:
 
void Main()
{
    WeatherData weatherData = new WeatherData();
 
            CurrentConditionsDisplay currentDisplay = new CurrentConditionsDisplay(weatherData);
 
            weatherData.setMeasurements(80F, 65F, 30.4F);
            weatherData.setMeasurements(82F, 70F, 29.2F);
            weatherData.setMeasurements(78F, 90F, 29.2F);
}
 
 public class CurrentConditionsDisplay: Observer, DisplayElement
    {
        private float temperature;
        private float humidity;
        private Subject weatherData;
 
        public CurrentConditionsDisplay(Subject weatherData)
        {
            this.weatherData = weatherData;
            weatherData.registerObserver(this);
        }
 
        public void update(float temperature, float humidity, float pressure)
        {
            this.temperature = temperature;
            this.humidity = humidity;
            display();
        }
 
        public void display()
        {
            Console.WriteLine("Current conditions: " + temperature + "F degrees and " + humidity + "% humidity");
        }
    }
    
public interface Observer
    {
        void update(float temp, float humidity, float pressure);
    }
 
    public interface DisplayElement
    {
        void display();
    }
 
public interface Subject
    {
        void registerObserver(Observer o);
        void removeObserver(Observer o);
 
        void notifyObservers();
    }
 
public class WeatherData: Subject
    {
        private ArrayList observers;
        private float temperature;
        private float humidity;
        private float pressure;
 
        public WeatherData()
        {
            observers = new ArrayList();
        }
 
 
        public void registerObserver(Observer o)
        {
            observers.Add(o);
        }
 
        public void removeObserver(Observer o)
        {
            int i = observers.IndexOf(o);
            if (i >= 0)
            {
                observers.RemoveAt(i);
            }//if
        }
 
        public void notifyObservers()
        {
            for (int i = 0; i < observers.Count; i++)
            {
                Observer observer = (Observer)observers[i];
                observer.update(temperature, humidity, pressure);
            }
        }
 
        public void setMeasurements(float temperature, float humidity, float pressure)
        {
            this.temperature = temperature;
            this.humidity = humidity;
            this.pressure = pressure;
            measurementsChanged();
        }
 
        private void measurementsChanged()
        {
            notifyObservers();
        }
    }


If you are looking to use .NET's built-in IObservable interface, you can read more about that here: http://msdn.microsoft.com/en-us/library/dd990377%28v=vs.110%29.aspx

For an example of the Observer Design Pattern based on implementing the IObservable interface, you can find that here: http://msdn.microsoft.com/en-us/library/ee850490%28v=vs.110%29.aspx

Leftover Patterns in Head First Design Patterns

If you have picked up the book "Head First Design Patterns", one of the unfortunate parts of this book is that there are no code samples associated with "leftover patterns".  Instead, the patterns are simply described very briefly.

The Leftover Patterns are:

  1. Bridge Pattern
  2. Builder Pattern
  3. Chain of Responsibility Pattern
  4. Flyweight Pattern
  5. Interpreter Pattern
  6. Mediator Pattern
  7. Memento Pattern
  8. Prototype Pattern
  9. Visitor Pattern

However, C# 3.0 Design Patterns (http://shop.oreilly.com/product/9780596527730.do) DOES cover these Leftover Patterns!!

You can read up more about these patterns here as well as download associated Example Code: http://patterns.cs.up.ac.za/


The Strategy Pattern in C#

The Strategy Pattern is one of the most basic Design Patterns and is largely based on the OOP Principle of favoring Composition over Inheritance.

The Strategy Pattern is officially defined as:

The Strategy Pattern defines a family of algorithms, encapsulates each one, and makes them interchangeable.  Strategy lets the algorithm vary independently from clients that use it. (Head First Design Patterns-Intro to Design Patterns)

Below is an implementation of the Strategy Pattern in C#:
 
void Main()
{
    Duck mallard = new MallardDuck();
            mallard.performQuack();
            mallard.performFly();
 
            Duck model = new ModelDuck();
            model.performFly();
            model.SetFlyBehavior = new FlyRocketPowered();
            model.performFly();
 
            
}
 
public abstract class Duck
    {
        protected FlyBehavior flyBehavior;
        protected QuackBehavior quackBehavior;
 
        public Duck()
        {
 
        }
 
        public FlyBehavior SetFlyBehavior
        {
            get
            {
                return flyBehavior;
            }
            set
            {
                flyBehavior = value;
            }
 
        }
 
        public QuackBehavior SetQuackBehavior
        {
            get
            {
                return quackBehavior;
            }
            set
            {
                quackBehavior = value;
            }
        }
 
        public abstract void display();
 
        public void performFly()
        {
            flyBehavior.fly();
        }
 
        public void performQuack()
        {
            quackBehavior.quack();
        }
 
        public void swim()
        {
            Console.WriteLine("All ducks float, even decoys!");
        }
 
    }
 
    public class MallardDuck : Duck
    {
        public MallardDuck()
        {
            quackBehavior = new Quack();
            flyBehavior = new FlyWithWings();
 
        }
        public override void display()
        {
            Console.WriteLine("I'm a real Mallard duck");
        }
    }
 
    public class ModelDuck : Duck
    {
        public ModelDuck()
        {
            flyBehavior = new FlyNoWay();
            quackBehavior = new Quack();
        }
        public override void display()
        {
            Console.WriteLine("I'm a model duck");
        }
    }
    
     public interface FlyBehavior
    {
        void fly();
    }
 
 public class FlyWithWings: FlyBehavior
    {
        public void fly()
        {
            Console.WriteLine("I'm flying!");
        }
    }
 
    public class FlyNoWay : FlyBehavior
    {
        public void fly()
        {
            Console.WriteLine("I can't fly");
        }
    }
 
    public class FlyRocketPowered : FlyBehavior
    {
        public void fly()
        {
            Console.WriteLine("I'm flying with a rocket!");
        }
    }
    
    public class Quack: QuackBehavior
    {
        public void quack()
        {
            Console.WriteLine("Quack");
        }
    }
 
    public class MuteQuack : QuackBehavior
    {
        public void quack()
        {
            Console.WriteLine("<<Silence>>");
        }
    }
 
    public class Squeak : QuackBehavior
    {
        public void quack()
        {
            Console.WriteLine("Squeak");
        }
    }
    
    public interface QuackBehavior
    {
        void quack();
    }



Tuesday, June 24, 2014

Debugging in LINQPad

If you have ever used LINQPad (http://www.linqpad.net/) for writing and testing out your LINQ Queries, you may have noticed that there are no built-in debugging tools in the LINQPad IDE for setting breakpoints etc.

Fortunately, however, you can use Visual Studio to debug into your LINQ queries that you compose in LINQPad!!

You simply follow these steps to be able to step into your LINQPad queries:

  1. Add the following code to your LINQPad query where you want a breakpoint 
    if(Debugger.IsAttached)
        {
            Debugger.Break();
        }

  2. From within Visual Studio, open the Debug menu and select Attach to Process
  3. Select the LINQPad.exe process and click on the Attach button
  4. Execute your LINQ query within LINQPad
  5. Notice that the LINQ query gets pulled into Visual Studio for debugging allowing you to step through the code!



Monday, June 23, 2014

The Adapter Pattern in C#

If you need to ever get a class to conform to another interface to provide uniform or predictable functionality, chances are that you will need to use the Adapter Design Pattern.

You can basically think of "real world" adapters such as the AC/DC Power Adapters that you will find with a wide variety of electronic devices or the adapters that you need for power outlets when you travel internationally.

The formal definition of the Adapter Pattern is the following:

The Adapter Pattern converts the interface of a class into another interface the clients expect.  Adapter lets classes work together that couldn't otherwise because of incompatible interfaces (Head First Design Patterns-the adapter pattern)

Since the Head First Design Patterns deals with sample code in Java, I have provided a C# implementation for you instead:

void Main()
{
    MallardDuck duck = new MallardDuck();
 
            WildTurkey turkey = new WildTurkey();
            Duck turkeyAdapter = new TurkeyAdapter(turkey);
 
            Console.WriteLine("The Turkey says....");
            turkey.gobble();
            turkey.fly();
 
            Console.WriteLine("\nThe Duck says....");
            testDuck(duck);
 
            Console.WriteLine("\nThe TurkeyAdapter says...");
            testDuck(turkeyAdapter);
 
}
 
static void testDuck(Duck duck)
        {
            duck.quack();
            duck.fly();
        }
        
public interface Duck
    {
        void quack();
        void fly();
    }
    
  public class MallardDuck : Duck
    {
        public void quack()
        {
            Console.WriteLine("Quack");
        }
 
        public void fly()
        {
            Console.WriteLine("I'm flying");
        }
    }
    
    public interface Turkey
    {
        void gobble();
        void fly();
    }
    
     public class WildTurkey : Turkey
    {
        public void gobble()
        {
            Console.WriteLine("Gobble gobble");
        }
 
        public void fly()
        {
            Console.WriteLine("I'm flying a short distance");
        }
    }
    
     public class TurkeyAdapter: Duck
    {
        private Turkey turkey;
 
        public TurkeyAdapter(Turkey turkey)
        {
            this.turkey = turkey;
        }
        public void quack()
        {
            turkey.gobble();
        }
 
        public void fly()
        {
            for (int i = 0; i < 5; i++)
            {
                turkey.fly();
            }//for
        }
    }

Sunday, June 22, 2014

The Abstract Factory Pattern in C#


The Abstract Factory Pattern builds upon the Factory Method pattern and adds Object Composition to the mix.
The Abstract Factory Pattern is officially defined as the following:
The Abstract Factory Pattern provides an interface for creating families of related or dependent objects without specifying their concrete classes. (Head First Design Patterns-the factory pattern)

In “Head First Design Patterns”, the Abstract Factory pattern extends upon the use of the Factory Method by adding control of the various ingredients needed by each of the Pizza Stores.  Therefore, a NY Pizza Store will receive a different set of ingredients vs a Chicago Pizza Store even though the ingredient types are common (sauce, cheese, veggies etc.).
 
Below is the basic pattern code in C# for your review (ingredient classes are left out since they are simple shell classes):
 
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using AbstractFactoryPattern;
 
namespace AbstractFactoryPattern
{
    class Program
    {
        static void Main(string[] args)
        {
            PizzaStore nyStore = new NYPizzaStore();
            Pizza pizza = nyStore.orderPizza("cheese");
            Console.WriteLine("Ethan ordered a " + pizza.Name + "\n");
            Console.ReadKey();
        }
    }
}
 
 
public interface PizzaIngredientFactory
{
  Dough createDough();
  Sauce createSauce();
  Cheese createCheese();
  List<Veggies> createVeggies();
  Pepperoni createPepperoni();
  Clams createClam();
 }//interface
 
public class NYPizzaIngredientFactory: PizzaIngredientFactory
{
  public Dough createDough()
    {
      return new ThinCrustDough();
     }
   public Sauce createSauce()
    {
      return new MarinaraSauce();
     }
    public Cheese createCheese()
    {
       return new ReggianoCheese();
    }
    public List<Veggies> createVeggies()
    {
      List<Veggies> veggies = new List<Veggies> {new Garlic(), new Onion(), new Mushroom(), new RedPepper()};
      return veggies;
    }
    public Pepperoni createPepperoni()
    {
      return new SlicedPepperoni();
     }
     
     public Clams createClam()
     {
       return new FreshClams();
     }
}//class NYPizzaIngredientFactory
 
public class CheesePizza: Pizza
{
  PizzaIngredientFactory ingredientFactory;
  
  public CheesePizza(PizzaIngredientFactory ingredientFactory)
    {
      this.ingredientFactory = ingredientFactory;
    }
    
    public override void prepare()
    {
      Console.WriteLine("Preparing " + this.name);
      dough = ingredientFactory.createDough();
      sauce = ingredientFactory.createSauce();
      cheese = ingredientFactory.createCheese();
     }
}
 
 
// Define other methods and classes here
public abstract class Pizza
{
protected string name;
protected Dough dough;
protected Sauce sauce;
protected List<Veggies> veggies;
protected Cheese cheese;
protected Pepperoni pepperoni;
protected Clams clam;
 
public abstract void prepare();
    
public void bake()
    {
    Console.WriteLine("Bake for 25 minutes at 350");
    }//bake
    
public void cut()
    {
      Console.WriteLine("Cutting the pizza into diagonal slices");
    }//cut
    
public void box()
    {
      Console.WriteLine("Place piza in official PizzaStore box");
    }//box
    
public string Name
    {
    get
        {
        return name;
        }
    set
        {
        name = value;
        }
    }//property: Name
 
    public override string ToString()
    {
        return name;
    }
}
    
public class NYStyleCheesePizza: Pizza
{
    private PizzaIngredientFactory ingredientFactory;
    public NYStyleCheesePizza(PizzaIngredientFactory ingredientFactory)
    {
        this.ingredientFactory = ingredientFactory;
        }
 
    public  override  void prepare()
    {
        Console.WriteLine("Preparing " + name);
        dough = ingredientFactory.createDough();
        sauce = ingredientFactory.createSauce();
        cheese = ingredientFactory.createCheese();
    }
    }//class: NYStyleCheesePizza
    
public abstract class PizzaStore
{
  public Pizza orderPizza(string type)
    {
    Pizza pizza;
    
    pizza = createPizza(type);
    
    pizza.prepare();
    pizza.bake();
    pizza.cut();
    pizza.box();
    
    return pizza;
    }
    
    protected abstract Pizza createPizza(string type);
}//class: PizzaStore
 
public class NYPizzaStore: PizzaStore
{
    protected override Pizza createPizza(string item)
    {
      Pizza pizza = null;
      PizzaIngredientFactory ingredientFactory = new NYPizzaIngredientFactory();
    if (item.Equals("cheese"))
    {
     pizza = new NYStyleCheesePizza(ingredientFactory);
     pizza.Name = "New York Style Cheese Pizza";
        return pizza;
    }//if
    else
    {
      return null;
    }//else
    }
}//class: NYPizzaStore

 

 

The Factory Method Pattern in C#


If you are not familiar with the Factory Method pattern, it is a well known design pattern officially defined as the following:
The Factory Method Pattern defines an interface for creating an object, but lets subclasses decide which class to instantiate.  Factory Method lets a class defer instantiation to subclasses.  (Head First Design Patterns-the factory pattern)
In the example provided in the book “Head First Design Patterns”, essentially a Pizza Store has grown into a franchise that needs to create different styles of pizzas based on different Pizza Stores in the franchise.  So how is that handled?  Essentially, allowing each Pizza Store in the franchise decide how to make the various styles of pizzas they will be creating (through subclasses/inheritance) but providing the overall framework for how the pizzas will be created.
The original source code is provided in Java in this book, therefore, I have provided a C# version for .NET Developers who want to begin using this pattern in their own development:
void Main()

{

    PizzaStore nyStore = new NYPizzaStore();

    Pizza pizza = nyStore.orderPizza("cheese");

    Console.WriteLine("Ethan ordered a " + pizza.Name + "\n");

}

 

 

 

// Define other methods and classes here

public abstract class Pizza

{

protected string name;

protected string dough;

protected string sauce;

protected ArrayList toppings = new ArrayList();

 

public void prepare()

    {

    Console.WriteLine("Preparing " + name);

    Console.WriteLine("Tossing dough....");

    Console.WriteLine("Adding sauce...");

    Console.WriteLine("Adding toppings:");

    for (int i=0; i< toppings.Count; i++)

    {

      Console.WriteLine(" " + toppings[i]);

     }//for

    }//prepare

    

public void bake()

    {

    Console.WriteLine("Bake for 25 minutes at 350");

    }//bake

    

public void cut()

    {

      Console.WriteLine("Cutting the pizza into diagonal slices");

    }//cut

    

public void box()

    {

      Console.WriteLine("Place piza in official PizzaStore box");

    }//box

    

public string Name

    {

    get

        {

        return name;

        }

    }//property: Name

}

    

public class NYStyleCheesePizza: Pizza

    {

    public NYStyleCheesePizza()

        {

          name = "NY Style Sauce and Cheese Pizza";

          dough = "Thin Crust Dough";

          sauce = "Marinara Sauce";

          toppings.Add("Grated Reggiano Cheese");

        }

    }//class: NYStyleCheesePizza

    

public abstract class PizzaStore

{

  public Pizza orderPizza(string type)

    {

    Pizza pizza;

    

    pizza = createPizza(type);

    

    pizza.prepare();

    pizza.bake();

    pizza.cut();

    pizza.box();

    

    return pizza;

    }

    

    protected abstract Pizza createPizza(string type);

}//class: PizzaStore

 

public class NYPizzaStore: PizzaStore

{

    protected override Pizza createPizza(string item)

    {

    if (item.Equals("cheese"))

    {

     return new NYStyleCheesePizza();

    }//if

    else

    {

      return null;

    }//else

    }

}//class: NYPizzaStore

    

Saturday, June 21, 2014

Installing Jetbrains TeamCity 8.12

If you currently use an older version of Team Foundation Server and want to upgrade to a new version of Visual Studio for your continuous integration builds, unfortunately, you are out of luck.

For example, Team Foundation Server 2013 supports Visual Studio 2010 and Visual Studio 2013 Build Controllers/Build Runners, however, Team Foundation Server 2010 will only support Visual Studio 2010 Build Controllers.

So what do you do if you do not have control over upgrading your base Team Foundation Server instance and still want to leverage Continuous Integration builds as part of  your software development process?

You use a 3rd party Continuous Integration build solution such as Jetbrains TeamCity!!

Below are screenshots on how to install Jetbrains TeamCity v. 8.12:





















Tuesday, June 17, 2014

Administration Page for ASP.NET VirtualPathProvider


If you read this Microsoft Support article: http://support.microsoft.com/kb/910441, you will notice that the Administration Page provided is very primitive and will not display any content if the database is empty.  Of course, you can manually edit the content in the database, but it is probably easier to have an Administration Page that will help you initially load that content directly into the database.
I am partial to the Telerik RadControls, therefore, I used the Telerik RadGrid control in my Administration Page, but you can use whichever control you prefer.  Below is the sample code that I used for my Administration Page:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="SharePointAdministrationPage.aspx.cs" Inherits="SPVPP.SharePointAdministrationPage" %>

 

<%@ register assembly="Telerik.Web.UI" namespace="Telerik.Web.UI" tagprefix="telerik" %>

 

<!DOCTYPE html>

 

<html xmlns="http://www.w3.org/1999/xhtml">

<head runat="server">

    <title></title>

</head>

<body>

    <form id="form1" runat="server">

        <telerik:radscriptmanager id="RadScriptManager1" runat="server">

            <scripts>

                <asp:scriptreference assembly="Telerik.Web.UI" name="Telerik.Web.UI.Common.Core.js"></asp:scriptreference>

                <asp:scriptreference assembly="Telerik.Web.UI" name="Telerik.Web.UI.Common.jQuery.js"></asp:scriptreference>

                <asp:scriptreference assembly="Telerik.Web.UI" name="Telerik.Web.UI.Common.jQueryInclude.js"></asp:scriptreference>

            </scripts>

        </telerik:radscriptmanager>

        <div>

            <telerik:radgrid id="RadGrid1" runat="server" autogeneratecolumns="False" datasourceid="SqlDataSource1" allowautomaticinserts="True" allowautomaticupdates="True" cellspacing="-1" gridlines="Both">

                <mastertableview datakeynames="FileName" datasourceid="SqlDataSource1" commanditemdisplay="Top" allowautomaticinserts="True" allowautomaticupdates="True" nomasterrecordstext="No records found">

                    <commanditemsettings showaddnewrecordbutton="True" showcancelchangesbutton="True" showrefreshbutton="True"></commanditemsettings>

                    <columns>

                        <telerik:grideditcommandcolumn buttontype="ImageButton" uniquename="EditCommandColumn" />

                        <telerik:gridboundcolumn datafield="FileName" filtercontrolalttext="Filter FileName column" headertext="FileName" sortexpression="FileName" uniquename="FileName">

                        </telerik:gridboundcolumn>

                        <telerik:gridboundcolumn datafield="FileData" filtercontrolalttext="Filter FileData column" headertext="FileData" sortexpression="FileData" uniquename="FileData">

                        </telerik:gridboundcolumn>

                        <telerik:gridhyperlinkcolumn datatextfield="VirtualPath" target="_self" headertext="Virtual Path" datanavigateurlformatstring="{0}" datanavigateurlfields="VirtualPath" />

                        <telerik:gridbuttoncolumn text="Delete" commandname="Delete" buttontype="ImageButton" />

                    </columns>

                    <editformsettings editformtype="Template">

                        <formtemplate>

                            <table id="Table3" cellspacing="1" cellpadding="1" width="100%" border="0">

 

                                <tr>

                                    <td>FileName:

                                    </td>

                                    <td>

                                        <asp:textbox id="txtFileName" runat="server" text='<%# Bind("FileName") %>' />

                                    </td>

                                </tr>

                                <tr>

                                    <td>FileData:

                                    </td>

 

                                    <td>

                                        <telerik:radeditor id="txtFileDataContent" runat="server" content='<%#Bind("FileData") %>'></telerik:radeditor>

                                    </td>

                                </tr>

                                <tr>

                                    <td>VirtualPath:

                                    </td>

                                    <td>

                                        <asp:textbox id="txtVirtualPath" runat="server" text='<%# Bind("VirtualPath") %>' />

                                    </td>

                                </tr>

                                <tr>

                                    <td align="right" colspan="2">

                                        <asp:button id="btnUpdate" text='<%# (Container is GridEditFormInsertItem) ? "Insert" : "Update" %>'

                                            runat="server" commandname='<%# (Container is GridEditFormInsertItem) ? "PerformInsert" : "Update" %>'></asp:button>&nbsp;

                                <asp:button id="btnCancel" text="Cancel" runat="server" causesvalidation="False"

                                    commandname="Cancel"></asp:button>

                                    </td>

                                </tr>

                        </formtemplate>

                    </editformsettings>

                </mastertableview>

            </telerik:radgrid>

            <asp:sqldatasource id="SqlDataSource1" runat="server"

                connectionstring="<%$ ConnectionStrings:VirtualProviderDBConnectionString %>" insertcommand="USP_INSERT_PAGE" insertcommandtype="StoredProcedure" selectcommand="USP_SELECT_PAGE" selectcommandtype="StoredProcedure" updatecommand="USP_EDIT_PAGE" updatecommandtype="StoredProcedure">

                <insertparameters>

                    <asp:parameter name="FileName" type="String" />

                    <asp:parameter name="FileData" type="String" />

                    <asp:parameter name="VirtualPath" type="String" />

                </insertparameters>

                <updateparameters>

                    <asp:parameter name="FileName" type="String" />

                    <asp:parameter name="FileData" type="String" />

                    <asp:parameter name="VirtualPath" type="String" />

                </updateparameters>

            </asp:sqldatasource>

        </div>

    </form>

</body>

</html>
I also used stored procedures to manage my Select, Insert and Update commands to provide greater security for inserting such content directly into the database.

Monday, June 16, 2014

Code Syntax Editor for ASP.NET

If you are looking for code syntax editors for ASP.NET Web Forms, they are definitely hard to find since most Internet searches will return search results for HTML Editors for ASP.NET Web Forms rather than Code Syntax Editors/Code Highlighters.

Fortunately, there is one such Code Syntax Editor available for ASP.NET Web Forms and best of all, it is FREE!

You can download CodeHighlighter from here: http://www.actiprosoftware.com/products/controls/aspnet/codehighlighter

There are a few things to note about the Code Highlighter:

  1. Unlike most HTML Editors, it is not a full blown editor for editing code and providing immediate syntax highlighting.  Instead, it works on existing ASP.NET Web Forms controls such as a Textbox control and providing the appropriate syntax highlighting.
  2. Unfortunately, the control was built on ASP.NET v. 2.0 and does not appear to have been updated in quite some time.  As far as I can tell, there is not an updated release for .NET v. 4.0/4.5.
  3. The sample project that ships with the free download is not a functional Web Application project.  Instead, it is compiled as a Class Library project.  Therefore, you will have to manually create a new Web Application project and manually import the files, add the appropriate project references and modify the Web.config to contain the appropriate configuration settings.
  4. The sample project that ships with the download is a VB.NET project.  Therefore, if you are working in C#, you will have to manually convert over the VB.NET over to C# in order to use the corresponding C# code in your application.
Below is a screenshot of the resulting Web Page running Code Highlighter:

 

Sunday, June 15, 2014

Implementing an ASP.NET VirtualPathProvider

If you are looking to implement a VirtualPathProvider for rendering virtual .aspx pages (such as from a database) rather than directly from the File System (similar to how SharePoint renders pages), then you will definitely want to follow this article:  http://support.microsoft.com/kb/910441

Unfortunately, the article leaves out some critical information:


  1. You will need to pre-populate the data into the database with some sample .aspx pages otherwise the AdministrationPage will not render
  2. The code to retrieve the information from the database and use it as part of the VirtualPathProvider is left out from the DBUtility class!!


However, after reading through some of the comments, I was able to fill in the missing information in order to be able to get a functional application rendering .aspx pages directly out of the database.

Below is the complete DBUtility code for your viewing pleasure:

using System;

using System.Collections;

using System.Collections.Generic;

using System.Configuration;

using System.Data.SqlClient;

using System.IO;

using System.Linq;

using System.Text;

 

namespace SPVPP

{

    public class DBUtility

    {

        SqlConnection cnn;

        private string connectionString = ConfigurationManager.ConnectionStrings["VirtualProviderDBConnectionString"].ConnectionString;

 

        //Run a select query to obtain all files and their content, and 

        //store the result in a in memory hashtable to obtain fast access.    

        string cmdSelectAllFiles = "SELECT FileName,FileData FROM VirtualFileSystem";

        Hashtable virtualFiles = null;

 

        public DBUtility() { virtualFiles = new Hashtable(); }

 

        public Hashtable GetVirtualFiles()

        {

            /* 1. Open a connection.  

               2. Select all the files.

               3. Iterate through the result and store the file name as a Key and

                  content as a Value in a hashtable.

               4. Finally return hashtable.

            */

            virtualFiles = new Hashtable();

            cnn = new SqlConnection(connectionString);

            cnn.Open();

 

            SqlCommand cmd = cnn.CreateCommand();

            cmd.CommandText = cmdSelectAllFiles;

 

            using (SqlDataReader sqlDr = cmd.ExecuteReader())

            {

                while (sqlDr.Read())

                {

                    virtualFiles.Add(sqlDr["FileName"],sqlDr["FileData"]);

                }//while

            }//using

 

            return virtualFiles;

        }

 

        public string GetFileContents(string virPath)

        {

            //Obtain a file name from the virtual path. 

            string fileName = ExtractFileName(virPath);

 

            string fileContents = string.Empty;

 

            //Ater you obtain the file name, find it in the hashtable, and then

            //return the content for that file from the Values collection.    

            foreach (DictionaryEntry pair in virtualFiles)

            {

                if (pair.Key.Equals(fileName))

                {

                    fileContents = virtualFiles[fileName].ToString();

                }//if

            }//foreach

 

            return fileContents;

        }

 

        private string ExtractFileName(string virPath)

        {

            //Extract a file name from the virtual path and return it.

            return Path.GetFileName(virPath);

        }

 

        public bool CheckIfFileExists(string virPath)

        {

            string fileName = ExtractFileName(virPath);

 

            //After you extract the file name, find it in the hashtable of 

            //virtual files. If the file name is found, return true. Otherwise, return false.    

            foreach (DictionaryEntry pair in virtualFiles)

            {

 

                if (pair.Key.Equals(fileName))

                {

                    return true;

                }//if

            }//foreach

 

            return false;

 

        }

    }

}

In addition, these MSDN articles may also be useful to you in implementing the VirtualPathProvider in conjunction with CacheDependencies: