Thursday, October 16, 2008

Improve speed of development for SharePoint (Part3) - Using in line scripts in SharePoint programming


I am often thinking about collecting the reasons that explains why development are sometimes taking so much time in SharePoint projects comparing to Asp .Net ones? In the main presentation post of this topic (improve your speed of development for SharePoint Part 1) I tracked two main reasons:
  1. Most of the server code you will have to write will have to be built before having to be tested.
  2. You will have to deploy the code you've just written on your development machine before testing it.
These numerous operations of building and deployment set a lot of time especially if they come along with IIS reset. If you compare with a Asp .Net project, the developer in the case of a pure Asp .Net, write his client and server code, and test it by just pressing F5 !
So I will try to think about way of developing SharePoint code in order to be as close as possible to the Asp .Net developper experience.
So to avoid the two noticed previous points, there is obvious things to do :
  • using scripts
  • working directly on pages that are below the 12 directory.

I will develop the "Using Scripts" topic in this post.

1 - Using in line scripts in SharePoint programming


You can program against WSS Object Model writting in line code in all the pages:
Master Pages
Layout Pages
Application Pages
Of course, for the two first type of Pages, it is a temporary solution, because it is not a best practice to use in line code in these pages since this code won't be able to execute if the page is customized.
To make in-line code run in master pages or layout pages (Site Pages) you have two solutions.

First, you can use in line script if you deploy the page with a feature, since the Site Pages and the in-line script run just fine as long as the pages remains uncustomized in a ghosted state, and deployment using a feature let master pages or content pages in a ghosted state.
Then you can use Visual Studio to modify the page. As the page is ghosted, if you modify the page file on the server, you will see changes appear in your web Site.
Regarding SharePoint Designer, you can use it if you open the page on the computer File Sytem using its physical path. But if you use SharePoint Designer and open the page using its url the page will stop working.
Why ?
Remember that WSS compiles a ghosted page into an assembly DLL for processing. However, as soon as a user modifies any aspect of this page with the SharePoint Designer after having open it using its URL, and moves the site page into an unghosted state, WSS then begins to use safe mode to process it. Because the page contains in-line script, WSS refuses to process it in safe mode and generates an error message.

So that leads to the second way of using in line script in Site Pages. Allowing WSS to process in line script in customized pages. For that you have to modify your web application web.config in order to allow in line code in this kind of pages.

cf.: SharePoint 2007: using ASP.NET server side code in your pages

Of course doing that on a production environment is not a good idea, but on the opposite, it can be a good idea to do it in a development environment. Doing that allows you to customize the pages that contain in line script and for example, to open this kind of pages by using their URL in SharePoint Designer to modify the in line script.

Of course, it will be much easier to test your in line script inside Application Pages (pages in the 12\TEMPLATE\LAYOUTS directory) since in line script is perfectly legal in these pages, and you won't have to use a feature to deploy the page or to modify the web.config to test your code.

Anyway, starting writing your functionality using in line code will make you save a lot of time since you won't have to build your code before testing it. You won't have neither to deploy your dll nor have to wait for IIS Reset or Pool Recycling. For exemple, when you plan to write a web part, write your web part functionality code inside an Application Page, and when it works, create a web part and paste your tested code inside of it.
Same thing for a component that has to be placed in a Layout Page. First write it and test it inside the layout page in an in line code format, then, when it works, paste the code inside a component.
And again the same for a feature receiver element...

In general, I think it's better to avoid .dll in SharePoint as often as possible :
  • web part,
  • Custom controls,
  • etc.
Reading Microsoft documentation on Server Controls, a Custom Control, as a compiled component, is planned to be shared between several applications. It is useless to create a custom control for one application.
It's better in this case to create an User Control (.ascx) or to use a Smart Part. The application performances will stay the same since by default, all is compiled in Asp .Net.
Doing that, you will improve your development speed, because you will just have to copy your in line script code in an .ascx or a Smart Part, and you will also improve the easyness of deployment and increase the maintanability of your application because there often will be no more .dll in your applications.
Regarding the question of choices in matter or applicative architecture there is the excellent post of Chris Johnson. You will, by the way, notice that custom controls in Layout pages are not mentioned.

2 - The two different kinds of in line script for SharePoint


there are two different ways writing in line server code script for SharePoint:
  • the best known one, the script block is placed between <script runat="server" > and </script > tags
  • less known (except for those who had to fight against it in SharePoint 2003 or did ASP) between <% and %> tags is called Embedded Code Blocks
I used to become fond of Embedded Code Blocks because for simple functionalities your code can be so clear since you keep your server code linked to your HTML structure. I mean, when you need to write somtehing at a specific place in your page, and need server code to do so, you can inject the minimal server code you need just close to the place where you need it.
So it may be easier later to understand your server code while reading the page code.
I use to use it in some of my other posts :

The difference between these two kinds of in line script (regarding syntax), is that you cannot declare classes or method in the second one, but both are working well together as shown is the following Application Page sample. Regarding performances, if you want to use Embedded Code Blocks in your real applications, I let to examine the consequences reading the previous mentioned article (Embedded Code Blocks ).
Personally I use Embedded Code Blocks to test a piece of code quickly, to make a quick POC for a customer presentation. After that I reuse the code in more standard containers (script block, ascx, code behind, web parts, control server, etc.)

3 - Code sample

Now, I want to show how easy it is to write in line code for SharePoint.
Copy the following code in a file you will call _test.aspx.
Open Visual Studio and drag and drop the file in Visual Studio.
Notice you have Intellisense for your custom class and your SharePoint objects !
No need to create a solution, a project, etc.
Test some code, write somehting using SharePoint Object Model...
Then click the "File" menu item in the top left corner of Visual Studio and click "Save _test.aspx As"



And copy the file in the SharePoint Application Pages directory:

C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\12\Template\Layouts

(trick: you will go there quicker with a "Shortcut to 12" on yourn desktop).



Then assume you have a SharePoint site in your computer with the "http://localhost/" url, open the Application Page by navigating to "http://localhost/_layouts/_test.aspx.

ou should obtain something like that:




<%@ Assembly Name="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Page Language="C#" %>
<%@ Import Namespace="Microsoft.SharePoint" %>
 
<script runat="server">
    //method
    public string WriteSomething()
    {
        return "something";
    }
    //method with a parameter
    public void writeAtTheTop(string something)
    {
        Response.Write(something);
    }
 
    //declaring a class
    public class myClass
    {
        //using methods inside
        public string WriteSomethingElse()
        {
            return "something else";
        }
        public string WriteWhatYouWant(string whatYouWant)
        {
            return whatYouWant;
        }
    }
 
</script>
 
<div>
    <!--writing a bloc of code-->
    <!-- and testing intellisense with SharePoint and possibility to program against WSS Object Model-->
    <%
        //using a method from the script runat server
        WriteSomething();
        //another method
        writeAtTheTop("I write at the top of the page.<br>");
        //declaring a variable
 
        string myWebTitle = string.Empty;
 
        using (SPWeb myWeb = SPContext.Current.Web)
        {
            myWebTitle = myWeb.Title;
        }
    %>
    <!--different ways of displaying values inside a page: -->
 
    <%=WriteSomething() %>
    <br />
 
    <!-- with an instance of the class declared inside the script block -->
    <%=new myClass().WriteSomethingElse()%>
    <br />
    <br />
 
    <!-- with a parameter-->
    <%=new myClass().WriteWhatYouWant("My Web Site Title is:")%>
    <br />
 
    <%-- reusing previous variable declared in the Embedded Code Block --%>
    <span style="color: Red">
        <%=new myClass().WriteWhatYouWant(myWebTitle)%>
    </span>
    <br />
    <br />
 
    <!-- testing again intellisense with SharePoint and possibility to program against WSS Object Model-->
    My Web Site Title is :
    <br />
    <%=SPContext.Current.Web.Title %>
</div>

Look at the previous code, 3 page directives, and here you are, you can start programming for SharePoint.

No comments: