Sunday, April 19, 2009

Use Linq inside a Script Block of an Application Page - SharePoint minimal configuration for Linq


When developing for SharePoint you maybe use Linq. Assume you are developing a new piece of code and to improve your development speed you have decided to test this code in an Application Page inside a Script Block.

Suddenly, you want to use a Linq instruction but you remind that your page is called by a web site of a new Web Application and this Web Application web.config has not been modified to use .Net 3.5 new features.
Actually, at this point it is very fast to activate the use of Linq.

  1. Modify your Application Page to have intellisense.

    You have two page directives to paste:

    the Assembly Page Directive to add a reference to the System.Core.dll (there is just one version of this dll the3.5 version)

    <%@ Assembly Name="System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" %>



    the Import Page Directive to specify the System.Linq Namespace 

    <%@ Import Namespace="System.Linq" %>


    From this point you will have Linq Intellisense in your Visual Studio 2008 Editor.



    So, you keep writing your code and obtain this page:



    <%@ Page Language="C#" %>

     

    <%@ Assembly Name="System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" %>

    <%@ Assembly Name="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>

    <%@ Import Namespace="Microsoft.SharePoint" %>

    <%@ Import Namespace="System.Linq" %>

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

    <head>

        <title></title>

    </head>

    <body>

        <script runat="server">

            void Page_Load(object sender, EventArgs e)

            {

                SPListCollection myListCollection = SPContext.Current.Web.Lists;

                var listQuery = from SPList aList in myListCollection where (aList.Title) == "Customers" select aList;

     

                if (listQuery.Count() > 0)

                {

                    Response.Write("<br>How many Customers ? <br>" + listQuery.ElementAt<SPList>(0).ItemCount);

                }

                else

                {

                    Response.Write("<br>" + "There is no list with this name");

                }

            } 

        </script>

    </body>

    </html>

     



     But if you try to execute the page you will get a compilation Exception from SharePoint.



  2. Modify your web.config

    To fix the Linq compilation issue open your Web Application web.config and paste this xml code just under the ending Tag of System.Web.


        </webParts>

        <machineKey validationKey="E150B1AD042FFFD037943E670D1ED5EE50FCA3A12F8782BE" decryptionKey="F3790C833070BFBE30590B9CC6380A0592DF229F0DA7E3E7" validation="SHA1" />

        <sessionState mode="SQLServer" timeout="60" allowCustomSqlDatabase="true" partitionResolverType="Microsoft.Office.Server.Administration.SqlSessionStateResolver, Microsoft.Office.Server, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" />

      </system.web>

      <!--Start adding Linq Compilation Instruction - Marc -->

      <system.codedom>

        <compilers>

          <compiler language="c#;cs;csharp" extension=".cs" warningLevel="4"

                    type="Microsoft.CSharp.CSharpCodeProvider, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">

            <providerOption name="CompilerVersion" value="v3.5"/>

            <providerOption name="WarnAsError" value="false"/>

          </compiler>

          <compiler language="vb;vbs;visualbasic;vbscript" extension=".vb" warningLevel="4"

                    type="Microsoft.VisualBasic.VBCodeProvider, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">

            <providerOption name="CompilerVersion" value="v3.5"/>

            <providerOption name="OptionInfer" value="true"/>

            <providerOption name="WarnAsError" value="false"/>

          </compiler>

        </compilers>

      </system.codedom>

      <!--End adding Linq Compilation Instruction - Marc -->

      <runtime>

        <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">

          <dependentAssembly>



    And you're done!



2 comments:

Unknown said...

Hi, this post was really helpfull but I have a strange problem. Everything works fine from the server machine, but users get the error when they browse from their computers. Any idea would be appriciated.

Tnx in advance

Marc Charmois said...

Hi,

the first explanation that comes to me is that your users are using a different web.config that is not configured for LINQ.
I guess you might have at least two different zones in your SharePoint Web Application, maybe one for an Intranet access, and the other one for an Internet access.
That means that you have two different IIS web sites one for the Intranet access and the other one for the Internet access.
So when you browse the site from the server you use the IIS site for Intranet access and its web.config seems to be configured properly for LINQ, but when your users try to do the same through the Internet, they reach the other IIS web site with a different web.config not configured properly for LINQ and get the error.

That would be an explanation...

Hope that helps.

Marc