让 SharePoint 支持 .NET 3.5

SharePoint 2007 是基于 .NET 2.0 开发,那 SharePoint 2007 支持 .NET 3.5 嘛? 答案是肯定的!任何 .NET 2.0 开发的程序包括都可以运行在 .NET 3.5 之上,可以充分利用 .NET 3.5 的新特性,包括 C# 3.5 的 LINQ,ASP.NET AJAX 等。

好吧,你说支持,那么我们就写一段 C#3.5 的代码吧:

1. 建一个 Document Library: BasicPages,Template 选择 Basic Page

2. 在 BasicPages 中New一新页面:NET35Test.aspx

3. 在 SharePoint Designer 打开

4. 贴入文末的代码

5. 按 F12 预览

6. 得到如下错误

Compiler Error Message: CS1526: A new expression requires () or [] after type

注意:如果你得到的是 Parser Error Message: Code blocks are not allowed in this file.,你可以先参考:
ERROR: Code blocks are not allowed in this file(此文件中不允许代码块) - SharePoint 2007 

到底支不支持啊?稍安勿躁,让我们往 web.config 添加如下配置节:

< configuration >
< system.codedom >
        
< compilers >
            
< compiler  language ="c#;cs;csharp"  extension =".cs"  type ="Microsoft.CSharp.CSharpCodeProvider,System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"  warningLevel ="4" >
                
< providerOption  name ="CompilerVersion"  value ="v3.5" />
                
< providerOption  name ="WarnAsError"  value ="false" />
            
</ compiler >
        
</ compilers >
    
</ system.codedom >
</ configuration >

 

 

重新刷新,得到如下错误,

Compiler Error Message: CS0234: The type or namespace name 'Linq' does not exist in the namespace 'System' (are you missing an assembly reference?)

Line 5: <%@ Import Namespace="System.Linq" %> 

LINQ 来了,看来有戏,继续往 web.config 添加如下配置节:onfiguration>
<system.web>
<compilation batch="false" debug="false">
      
<assemblies>
        
<add assembly="System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
      
</assemblies>
</compilation>
</system.web>
</configuration>

< configuration >
< system.web >
< compilation  batch ="false"  debug ="false" >
      
< assemblies >
        
< add  assembly ="System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" />
      
</ assemblies >
</ compilation >
</ system.web >
</ configuration >

 

重新刷新,啊哈结果出来:

让 SharePoint 支持 .NET 3.5_第1张图片

测试页面代码:

Code
<%-- _lcid="1033" _version="12.0.4518" _dal="1" --%>
<%-- _LocalBinding --%>
<%@ Page language="C#" MasterPageFile="~masterurl/default.master"    Inherits="Microsoft.SharePoint.WebPartPages.WebPartPage,Microsoft.SharePoint,Version=12.0.0.0,Culture=neutral,PublicKeyToken=71e9bce111e9429c" meta:webpartpageexpansion="full" meta:progid="SharePoint.WebPartPage.Document" %>
<%@ Register Tagprefix="SharePoint" Namespace="Microsoft.SharePoint.WebControls" Assembly="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %> <%@ Register Tagprefix="Utilities" Namespace="Microsoft.SharePoint.Utilities" Assembly="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %> <%@ Import Namespace="Microsoft.SharePoint" %> <%@ Register Tagprefix="WebPartPages" Namespace="Microsoft.SharePoint.WebPartPages" Assembly="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Import Namespace="System.Collections.Generic" %>
<%@ Import Namespace="System.Linq" %>

<script type="text/c#" runat="server">

    
/// <summary>
    /// 示例改编自MSDN:
    /// 如何:查询对象集合(C# 编程指南)
    /// http://msdn.microsoft.com/zh-cn/library/bb907066.aspx
    /// </summary>
    public class StudentClass
    {
        #region data

        protected enum GradeLevel { FirstYear 
= 1, SecondYear, ThirdYear, FourthYear };

        protected class Student
        {
            public string FirstName { get; set; }
            public string LastName { get; set; }
            public 
int ID { get; set; }
            public GradeLevel Year;
            public List
<int> ExamScores;
        }

        protected static List
<Student> students = new List<Student>
        {
            
new Student {FirstName = "Terry", LastName = "Adams", ID = 120, Year = GradeLevel.SecondYear, ExamScores = new List<int>99828179}},
            
new Student {FirstName = "Fadi", LastName = "Fakhouri", ID = 116, Year = GradeLevel.ThirdYear,ExamScores = new List<int>99869094}},
            
new Student {FirstName = "Hanying", LastName = "Feng", ID = 117, Year = GradeLevel.FirstYear, ExamScores = new List<int>93928087}},
            
new Student {FirstName = "Cesar", LastName = "Garcia", ID = 114, Year = GradeLevel.FourthYear,ExamScores = new List<int>97898582}},
            
new Student {FirstName = "Debra", LastName = "Garcia", ID = 115, Year = GradeLevel.ThirdYear, ExamScores = new List<int>35729170}},
            
new Student {FirstName = "Hugo", LastName = "Garcia", ID = 118, Year = GradeLevel.SecondYear, ExamScores = new List<int>92908378}},
            
new Student {FirstName = "Sven", LastName = "Mortensen", ID = 113, Year = GradeLevel.FirstYear, ExamScores = new List<int>88946591}},
            
new Student {FirstName = "Claire", LastName = "O'Donnell", ID = 112, Year = GradeLevel.FourthYear, ExamScores = new List<int>75849139}},
            
new Student {FirstName = "Svetlana", LastName = "Omelchenko", ID = 111, Year = GradeLevel.SecondYear, ExamScores = new List<int>97928160}},
            
new Student {FirstName = "Lance", LastName = "Tucker", ID = 119, Year = GradeLevel.ThirdYear, ExamScores = new List<int>68798892}},
            
new Student {FirstName = "Michael", LastName = "Tucker", ID = 122, Year = GradeLevel.FirstYear, ExamScores = new List<int>94929191}},
            
new Student {FirstName = "Eugene", LastName = "Zabokritski", ID = 121, Year = GradeLevel.FourthYear, ExamScores = new List<int>96859160}}
        };

        #endregion

        
//Helper method
        protected static int GetPercentile(Student s)
        {
            
double avg = s.ExamScores.Average();
            
return avg > 0 ? (int)avg / 10 : 0;
        }

        public string QueryHighScores(
int exam, int score)
        {
            StringBuilder sb 
= new StringBuilder();
            sb.Append(
"<pre style='font-size: 21px;'>");
            sb.Append(
"Hello MOSS 2007. You're running on .NET 3.5.\n\nPopulate students via LINQ:\n");
            
var highScores = from student in students
                             where student.ExamScores[exam] 
> score
                             select 
new { Name = student.FirstName, Score = student.ExamScores[exam] };
            sb.AppendFormat(
"{0,-15}{1}\n""Name""Score");
            foreach (
var item in highScores)
            {
                sb.AppendFormat(
"{0,-15}{1}\n", item.Name, item.Score);
            }
            sb.Append(
"</pre>");
            
return sb.ToString();
        }
    }
</script>

<asp:Content ContentPlaceHolderId="PlaceHolderPageTitle" runat="server">
    
<SharePoint:EncodedLiteral runat="server" text="<%$Resources:wss,webpagecreation_bp_title%>" EncodeMethod='HtmlEncode'/>
</asp:Content>
<asp:Content ContentPlaceHolderId="PlaceHolderMain" runat="server">
        
<% = new StudentClass().QueryHighScores(190%><WebPartPages:WebPartZone runat="server" ID="__WebPartPageLibraryZone__"><ZoneTemplate>
<WebPartPages:ContentEditorWebPart runat="server" __MarkupType="xmlmarkup" WebPart="true" __WebPartId="{658D1BBF-E074-44F3-98EC-A8363F60F4AD}" >
<WebPart xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://schemas.microsoft.com/WebPart/v2">
  
<Title>Content</Title>
  
<FrameType>None</FrameType>
  
<Description>Use for formatted text, tables, and images.</Description>
  
<IsIncluded>false</IsIncluded>
  
<PartOrder>1</PartOrder>
  
<FrameState>Normal</FrameState>
  
<Height />
  
<Width />
  
<AllowRemove>true</AllowRemove>
  
<AllowZoneChange>true</AllowZoneChange>
  
<AllowMinimize>false</AllowMinimize>
  
<AllowConnect>true</AllowConnect>
  
<AllowEdit>true</AllowEdit>
  
<AllowHide>true</AllowHide>
  
<IsVisible>true</IsVisible>
  
<DetailLink />
  
<HelpLink />
  
<HelpMode>Modeless</HelpMode>
  
<Dir>Default</Dir>
  
<PartImageSmall />
  
<MissingAssembly>Cannot import this Web Part.</MissingAssembly>
  
<PartImageLarge />
  
<IsIncludedFilter />
  
<ExportControlledProperties>true</ExportControlledProperties>
  
<ConnectionID>00000000-0000-0000-0000-000000000000</ConnectionID>
  
<ID>g_658d1bbf_e074_44f3_98ec_a8363f60f4ad</ID>
  
<ContentLink xmlns="http://schemas.microsoft.com/WebPart/v2/ContentEditor" />
          
<Content xmlns="http://schemas.microsoft.com/WebPart/v2/ContentEditor"><![CDATA[]]></Content>
  
<PartStorage xmlns="http://schemas.microsoft.com/WebPart/v2/ContentEditor" />
</WebPart>
</WebPartPages:ContentEditorWebPart>
</ZoneTemplate></WebPartPages:WebPartZone></asp:Content>

 

总结,全部工作都在 web.config 中完成,有两个地方需要配置

一是,配置 system.codedom/compilers/complier,指示编译器版本

二是,配置 system.web/compilation/assemblies,添加额外的.NET3.5程序集引用

以上两个配置节只需要从已存在的 ASP.NET 3.5 应用程序的 web.config 拷贝过去。

对于 sharepoint 的 webconfig 包含很多其特有属性,直接编辑是一件让人敬畏的事,很容易出错,一不小心就翘辫子了。

update 2009年1月15日 1:28:37

明天再介绍一种“自动化”的方法以及支持ASP.NET AJAX 的测试。

如何自动化升级 SharePoint 的 web.config 到 .NET 3.5 ? 这里充分利用在 Vistual Studio 2008 中切换 .NET 版本的时候自动化更新 web.config 的特性:

1. 新建一个 WebApplication 或者 WebSite,Target Framework 选择 .NET framework 2.0
2. 拷贝欲升级的 SharePoint web.config 替换新建站点的 web.config
3. 打开项目属性,选择 Application 选项卡
4. 在 Application 选项卡中,Target Framework 选择 .NET framework 3.5
5. OK,VS 自动帮你更新 web.config 中 ASP.NET 3.5 相关配置节,包括 ASP.NET AJAX
6. 将升级的 web.config 覆盖旧的 SharePoint 站点下的 web.config (注意一定要养成习惯先备份,不能保证更新的web.config完全兼容)

update 2009年2月5日11:22:39

在 Windows SharePoint Services 3.0 版中安装 ASP.NET 2.0 AJAX Extensions 1.0

你可能感兴趣的:(让 SharePoint 支持 .NET 3.5)