跳到主内容

SharePoint 社区

SharePoint RSS 源-阅读最新文章
搜索
楠木科技
SharePoint社区
SharePoint讨论版
Team Blog
SharePoint 2010
会员中心
留言
  

SharePoint学习、交流的社区
SharePoint & MOSS Event Handler(Event Receiver)中使用HttpContext or SPContext.Current

    SharePoint开发中经常会用到HttpContext.Current和SPContext.Current来获取数据,如我们通过HttpContext.Current获取Request、Response等信息,通过SPContext.Current获取Web、CurrentUser、Site、SPListItem等等,在EventHandler(EventReceiver)中也不例外,但是如果我们在EventHandler(EventReceiver)使用了HttpContex.Current或SPContext.Current则会出现Null Reference Exception (空引用错误),下面介绍使用时的注意事项。

    因为EventHandler 和HttpContext.Current在不同的线程(暂且这样理解,其实这种说法不明确),在ItemAdding、ItemAdded、ItemUpdating、ItemUpdated、ItemDeleting、ItemDeleted等方法中直接使用HttpContext时会出现Null引用错误,因为这个时候HttpContext.Current确实是不存在的,根据经验可以通过如下两种方式引用HttpContext.Current对象:

  • 在EventReceiver的构造函数中用对象将HttpContext.Current引用到当前类对象

此方法仅适用于ItemAdding和ItemUpdating,Demo如下:

public class HttpContextTestReceiver: SPItemEventReceiver

{

HttpContext context = null;

 

public HttpContextTestReceiver()

: base()

{

context = HttpContext.Current;

}

 

void WriteInfo(SPItemEventProperties properties)

{

Debug.WriteLine("** begin " + properties.EventType + " **");

 

if (null == context)

{

Debug.WriteLine("context is null.");

}

else

{

Debug.WriteLine(context.Request.RawUrl);

}

 

Debug.WriteLine("** end " + properties.EventType + " **");

}

 

public override void ItemAdding(SPItemEventProperties properties)

{

WriteInfo(properties);

}

 

public override void ItemAdded(SPItemEventProperties properties)

{

WriteInfo(properties);

}

 

public override void ItemUpdating(SPItemEventProperties properties)

{

WriteInfo(properties);

}

 

public override void ItemUpdated(SPItemEventProperties properties)

{

WriteInfo(properties);

}

 

public override void ItemDeleting(SPItemEventProperties properties)

{

WriteInfo(properties);

}

 

public override void ItemDeleted(SPItemEventProperties properties)

{

WriteInfo(properties);

}

}

执行完输出结果如下:

** begin ItemAdding **

/moss/alcatel/pgb/Lists/Links/NewForm.aspx?RootFolder=%2fmoss%2falcatel%2fpgb%2fLists%2fLinks&Source=http%3a%2f%2fnanmutech%3a8680%2fmoss%2falcatel%2fpgb%2fLists%2fLinks%2fAllItems.aspx

** end ItemAdding **

** begin ItemAdded **

context is null.

** end ItemAdded **

** begin ItemUpdating **

/moss/alcatel/pgb/Lists/Links/EditForm.aspx?ID=3&Source=http%3a%2f%2fnanmutech%3a8680%2fmoss%2falcatel%2fpgb%2fLists%2fLinks%2fAllItems.aspx

** end ItemUpdating **

context is null.

** end ItemUpdated **

** begin ItemDeleting **

context is null.

** end ItemDeleting **

** begin ItemDeleted **

context is null.

** end ItemDeleted **

可见此方法只适用于ItemAdding 和 ItemUpdating。

  • 通过HttpRunttime.Cache来传递HttpContex.Currentt对象

此方法适用于所有事件,但实现有点麻烦,需要在页面中添加一个控件,并在控件的OnLoad 事件中将HttpContext.Current缓存到HttpRuntime.Cache中,Demo如下:

  1. 创建一个WebPart

public class HttpContextTestPart: WebPart

{

protected override void OnLoad(EventArgs e)

{

base.OnLoad(e);

 

if (!Page.IsPostBack)

{

// use the current user login name as key, add the httpcontext to HttpRuntime.Cache

HttpRuntime.Cache.Add(HttpContext.Current.User.Identity.Name.ToLower(), HttpContext.Current, null,

DateTime.Now.AddMinutes(2), System.Web.Caching.Cache.NoSlidingExpiration, System.Web.Caching.CacheItemPriority.Normal, null);

}

}

}

  1. 创建一个EventReceiver

[CLSCompliant(false)]

public class HttpContextTestReceiver: SPItemEventReceiver

{

HttpContext context = null;

 

public HttpContextTestReceiver()

: base()

{

}

 

void WriteInfo(SPItemEventProperties properties)

{

context = HttpRuntime.Cache[properties.UserLoginName.ToLower()] as HttpContext;

 

     // remove form the cache

HttpRuntime.Cache.Remove(properties.UserLoginName.ToLower());

 

Debug.WriteLine("** begin " + properties.EventType + " **");

 

if (null == context)

{

Debug.WriteLine("context is null.");

}

else

{

Debug.WriteLine(context.Request.RawUrl);

}

 

Debug.WriteLine("** end " + properties.EventType + " **");

}

 

public override void ItemAdding(SPItemEventProperties properties)

{

WriteInfo(properties);

}

 

public override void ItemAdded(SPItemEventProperties properties)

{

WriteInfo(properties);

}

 

public override void ItemUpdating(SPItemEventProperties properties)

{

WriteInfo(properties);

}

 

public override void ItemUpdated(SPItemEventProperties properties)

{

WriteInfo(properties);

}

 

public override void ItemDeleting(SPItemEventProperties properties)

{

WriteInfo(properties);

}

 

public override void ItemDeleted(SPItemEventProperties properties)

{

WriteInfo(properties);

}

}

  1. 用Designer将WebPart添加到对应的页面,如NewForm.aspx, Editform.aspx,DisplayForm, AllItems.aspx等等

测试后输出的结果如下:

** begin ItemAdding **

/moss/alcatel/pgb/Lists/Links/NewForm.aspx?RootFolder=%2fmoss%2falcatel%2fpgb%2fLists%2fLinks&Source=http%3a%2f%2fnanmutech%3a8680%2fmoss%2falcatel%2fpgb%2fLists%2fLinks%2fAllItems.aspx

** end ItemAdding **

** begin ItemAdded **

/moss/alcatel/pgb/Lists/Links/EditForm.aspx?ID=3&Source=http%3a%2f%2fnanmutech%3a8680%2fmoss%2falcatel%2fpgb%2fLists%2fLinks%

** end ItemAdded **

** begin ItemUpdating **

/moss/alcatel/pgb/Lists/Links/EditForm.aspx?ID=3&Source=http%3a%2f%2fnanmutech%3a8680%2fmoss%2falcatel%2fpgb%2fLists%2fLinks%2fAllItems.aspx

** end ItemUpdating **

/moss/alcatel/pgb/Lists/Links/EditForm.aspx?ID=3&Source=http%3a%2f%2fnanmutech%3a8680%2fmoss%2falcatel%2fpgb%2fLists%2fLinks%

** end ItemUpdated **

** begin ItemDeleting **

/moss/alcatel/pgb/Lists/Links/AllItems.aspx

** end ItemDeleting **

** begin ItemDeleted **

/moss/alcatel/pgb/Lists/Links/AllItems.aspx

** end ItemDeleted **

 

可以看到每个事件中都可以取到HttpContext,但是用完之后要将HttpContext从缓存中删除。

如何让 MOSS & SharePoint 的Exception 信息显示到页面上
  大家都知道 MOSS & SharePoint 的开发中,调试错误信息不像常规的asp.net和winform开发,而且生产环境的服务器大部分情况下是不安装Visual studio开发工具的,这样对开发好的程序部署到 MOSS/Sharepoin 服务器上遇到错误更难获取有效错误信息,虽然通过 sharepoint 的 Log文件可以找到错误信息,但也是件麻烦的事情。
    做过asp.net开发的人员都知道,当asp.net的页面出错时,可以通过 <customErrors mode="Off" /> 来显示页面错误的详细信息,其实 MOSS / SharePoint 通过修改web.config文件也可以显示出错误详细的错误信息,操作步骤如下:
 
  • 进入 C:\inetpub\wwwroot\wss\VirtualDirectories\[端口] 下找到 web.config 文件;
  • 备份web.config文件;
  • 用记事本打开web.config,搜索 [<customErrors mode="On" />] 将mode改为 off;
  • 在记事本中搜索 [<SafeMode MaxControls="200" CallStack="false"], 将CallStack改为True;
  • 保存修改。

OK, 你可以看到熟悉的asp.net页面错误信息了。

MOSS & SharePoint 关闭 Alert Me 菜单的几种方法
适用产品:Microsoft Office SharePoint Server 2007(MOSS 2007), Windows SharePoint Services 3.0 (WSS3.0);
 
需求:关闭 Alert Me 菜单
 
分析/设计:在 SharePoint & MOSS 中带有 Alert me 菜单的位置有:
  • DispForm.aspx 页面中的工具栏
  • List / Library 视图工具栏上 Actions 菜单
  • List / Library 列表视图中, Item的菜单中
  • _layouts目录下的 UserDisp.aspx 页面(用户信息页面)的工具栏上 My Alerts

每个部位的关闭方法不同, 可以使用JS脚本实现,也可以通过 重载 TemplateControl实现,还可以通过权限控制实现。

实现方式:

实现方式
示例代码、操作
优缺点
JS脚本
hideListViewToolbarItems("Edit in Datasheet", "export to Spreadsheet",  
    "view rss feed","settings:create view");  
 
function hideListViewToolbarItems()  
{          
    var menuItem;     
    var menuItemName;  
    var menuItemIndex=-1;  
    var menuItemNames=new Array("edit in datasheet",   
      "open with windows explorer",  
      "connect to outlook",'export to spreadsheet','view rss feed','alert me' 
      ,"create column","settings:create view","list settings",  
      "document library settings","explorer view","all documents",  
      "all items","modify this view",   
      "view:create view","new document",  
      "new item","new folder","upload document",   
      "upload multiple documents");  
    var menuItems = new Array("EditInGridButton",   
      "OpenInExplorer","OfflineButton",  
      "ExportToSpreadsheet","ViewRSS",  
      "SubscribeButton","AddColumn",  
      "AddView","ListSettings","ListSettings",   
      "View1","DefaultView",  
      "DefaultView","ModifyView","CreateView",   
      "New0","New0",  
      "NewFolder","Upload","MultipleUpload");         
 
    var allMenuItems = document.getElementsByTagName('ie:menuitem');  
    for(var i = 0; i < hideListViewToolbarItems.arguments.length; i++ )   
    {                                 
        menuItemName= hideListViewToolbarItems.arguments[i].toLowerCase();  
        for (j=0; j < menuItemNames.length; j++)   
        {  
            if(menuItemNames[j]==menuItemName)  
            {                 
                menuItemIndex = j;  
                break;  
            }  
        }  
 
        menuItem=menuItems[menuItemIndex];  
                  
        for (var l = 0; l < allMenuItems.length; l++)  
        {         
            if(menuItemName.indexOf(":")!=-1)  
            {  
                menuItemName = menuItemName.split(":")[1];  
            }  
            if (allMenuItems[l].id.indexOf(menuItem)!=-1   
                && allMenuItems[l].text.toLowerCase() == menuItemName)  
            {         
                // For FireFox Compatibility  
                var parentNodeOfMenuItem = allMenuItems[l].parentNode;  
                parentNodeOfMenuItem.removeChild(allMenuItems[l]);  
                break;  
            }  
        }  
    }  

可以将脚本放到Master Page,可以灵活控制,缺点:非常规方式,对JS的要求较高
重载TemplateControl
打开 C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\CONTROLTEMPLATES\DefaultTemplates.ascx文件,SharePoint 在此文件中定义了 控件的模板,在相同目录下新建一个myTemplates.ascx页面,在DefaultTemplates.ascx文件中找到带有alert me的TemplateControl,将其copy到myTemplate.ascx文件、并进行修改(隐藏或删除alert me控件)
可以灵活控制每个部位的alert me菜单,
通过Feature的方式来做,可以灵活控制到每个站点,但工作量较大
通过权限控制实现 进入管理中心 -> Application Management 页面,进入web application general settings页面,选择相应的web application,将alert me设为off,进入 user permissions for web application 页面,将 list permission 组中的 [Create Alerts  -  Create e-mail alerts]前面的勾选项去掉、保存。 对web application下的所有网站集有效,不可以灵活控制,实现简单

MOSS/SharePoint自定义用户信息页面上的工具栏按钮
MOSS / SharePoint中的用户点击 欢迎信息菜单中的设置,进入到用户信息页面,可以看到 我的订阅、我的区域设置、编辑等按钮,我们可以通过如何方式修改工具栏上的这些按钮:
 
将下面的代码存为  myCostomUserDispView.ascx 文件到 C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\12\TEMPLATE\CONTROLTEMPLATES 目录下;
 
(用下面的示例代码可以移除 MyAlerts  和 My Regional Settings 按钮)
 
 
<%@ Control Language="C#"   AutoEventWireup="false" %>
<%@Assembly Name="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@Register TagPrefix="SharePoint" Assembly="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" namespace="Microsoft.SharePoint.WebControls"%>
<%@Register TagPrefix="SPHttpUtility" Assembly="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" namespace="Microsoft.SharePoint.Utilities"%>
<%@ Register TagPrefix="wssuc" TagName="ToolBar" src="~/_controltemplates/ToolBar.ascx" %>
<%@ Register TagPrefix="wssuc" TagName="ToolBarButton" src="~/_controltemplates/ToolBarButton.ascx" %>
<SharePoint:RenderingTemplate ID="UserInfoListDisplayFormToolBar" runat="server">
 <Template>
  <script>
   recycleBinEnabled = <SharePoint:ProjectProperty Property="RecycleBinEnabled" runat="server"/>;
  </script>
  <wssuc:ToolBar CssClass="ms-toolbar" id="toolBarTbl" runat="server" FocusOnToolbar=true>
    <Template_Buttons>
     <SharePoint:UserInfoListEditItemButton runat="server"/>
     <SharePoint:UserInfoListDeleteItemButton runat="server"/>
     <SharePoint:ChangePasswordButton runat="server"/>
     <%--<SharePoint:MyRegionalSettingsButton runat="server"/>--%>
     <%--<SharePoint:MyAlertsButton runat="server"/>--%>
     </Template_Buttons>
  </wssuc:ToolBar>
 </Template>
</SharePoint:RenderingTemplate>
 
 
SharePoint Designer 修改EditForm 实现 2个select 联动效果
 

SharePoint Designer 修改EditForm.aspx 页面,实现两个Select控件联动效果,实现方式:添加Load事件,在Load时给Select控件注册控件的onpropertychange事件。

 

/* Bengin of addLoadEvent, Form Load Event.  @Echo Liu*/

function addLoadEvent(func) {

  var oldonload = window.onload;

  if (typeof window.onload != 'function') {

    window.onload = func;

  } else {

    window.onload = function() {

      if (oldonload) {

        oldonload();

      }

      func();

    }

  }

}

var m_muLastSelectIndex = -1;

var m_processerArray;

var m_objMU;

var m_objProcessOwner;

/* Filter ProcessOwner by MU */

function FilterProcessorOwnerByMU()

{

if(m_objMU.selectedIndex != m_muLastSelectIndex)

{

m_muLastSelectIndex = m_objMU.selectedIndex;

var mu3 = m_objMU.options(m_muLastSelectIndex).value;

for(i = m_objProcessOwner.options.length - 1; i >= 0; i--)

{

m_objProcessOwner.options.remove(i);

}

for(i= 0; i < m_processerArray.length; i++)

{

var arrayPO = m_processerArray[i];

if(arrayPO[0].indexOf(mu3) == 0)

{

var oOption3 = document.createElement("OPTION");

m_objProcessOwner.options.add(oOption3);

oOption3.value = arrayPO[0];

oOption3.text = arrayPO[1];

}

}

}

}

function MUModelInitEvents()

{

var collSELECT = document.all.tags("SELECT");

for (i=0; i< collSELECT.length; i++)

    {

            var objCurrent = collSELECT(i);

            if(objCurrent.title == "MU")

            {

                    m_objMU = objCurrent;

            }

            else if(objCurrent.title == "ProcessOwner")

            {

                    m_objProcessOwner = objCurrent;

                    m_processerArray = new Array();

                    

                    for (j=0; j < objCurrent.options.length; j++)

                    {

                            m_processerArray[j] = new Array();

                            m_processerArray[j][0] = objCurrent.options(j).value;

                            m_processerArray[j][1] = objCurrent.options(j).text;

    }

            }

    }

   

    m_objMU.onpropertychange = FilterProcessorOwnerByMU;

    FilterProcessorOwnerByMU();

}

 

addLoadEvent(MUModelInitEvents);

addLoadEvent(function() {

  /* more code to run on page load */

});

/* End of addLoadEvent @Echo Liu */

1 - 5 下一步

 最新文章

展开/折叠 类别.NET WinForm ‎(2)
展开/折叠 类别asp.net技术 ‎(5)
展开/折叠 类别QFD知识 ‎(3)
展开/折叠 类别SharePoint技术 ‎(24)
展开/折叠 类别SharePoint应用 ‎(14)
展开/折叠 类别SilverLight ‎(5)
展开/折叠 类别乱七八糟 ‎(4)
展开/折叠 类别数据库技术 ‎(1)