2010年2月5日

Web.Config文件中的WebPartCache元素

Web Part的开发者能够使用Web Part cache来存储属性值, 加速数据的取出. web part cache中的值按照单个part方式, 或者是单个用户的方式来存储, 指定的方式是调用PartCacheReadPartCacheWrite 方法.

 

你能够决定使用的cache的类型- 要么是SharePoint 数据库, 要么是ASP.NET缓存对象- 通过配置web.config文件中的WebPartCache元素. 可能的值如下:

  • None 禁止缓存.
  • Database 使用SharePoint数据库做缓存
  • CacheObject 使用ASP.NET Cache object进行缓存(默认).

举个例子, 若要使用SharePoint 数据库做缓存, 你需要创建下面的web.config的entry:

<SharePoint>
  <WebPartCache Storage="Database"/>
</SharePoint>

 

缓存细节

=========

你可以使用WebPart class的PartCacheWritePartCacheRead来管理缓存, 还有PartCacheInvalidate方法来似的部分或全部的web part cache变为非法的(比如说, 如果web part的一个属性变了). 为了在运行时获得缓存的信息, 你需要使用CacheType属性.

 

寻找cache entry的方法是使用一个键值, 这允许任意数目的name-value pair被存储在cache中.

 

使用SharePoint Database

================

During cache storage in in the database, the following occurs:

  • If parts are not personalized, Personal cache entries (a call to the PartCacheWrite method with storage set to Storage.personal) are not stored.
  • If parts are Personal (added to the page in personal view), the Shared and Personal cache entries are stored in the same place. If the PartCacheInvalidate method is called with a storage value of Shared or Personal, all the cache is cleared.

When using the database for storage, both the Shared and Personal cache are limited to 2 MB. If this limit is exceeded, no error is displayed, but the cache entry will be lost. Additionally, if the storage type is Personal, it is charged against the user's quota.

 

Any object placed in the database cache must be marked as serializable (System.SerializableAttribute).

 

使用ASP.NET cache object

=================

ASP.NET also provides caching functionality that the Web Part can use through the Cache object.

 

Caches stored using ASP.NET are limited by the size allowed by the Cache object. For more information about the Cache class, see the System.Web.Caching namespace.

 

Note  Static Web Parts can only use caching if WebPartCacheStorage is set to CacheObject. No exception is raised if the setting is Database, but no cache entry is stored. Changes to the .aspx file cause the Web Part cache to get purged for static Web Parts.

 

资料来源:

Web Parts and Caching

http://msdn.microsoft.com/en-us/library/dd585600%28office.11%29.aspx

posted @ 2010-02-05 17:34 中道学友 阅读(34) 评论(0) 编辑

Assembly Binding Log Viewer(Fuslogvw.exe)

Assembly Binding Log Viewer 显示失败的程序集绑定(assembly binding). 这个信息可以帮助我们诊断为什么.NET Framework不能在运行时定位或寻找到一个程序集. 这些失败通常是将程序集部署到了错误的地方或者弄错了版本或是culture信息的结果. Common language runtime在找不到程序集的时候, 典型地会在你的程序中show出一个TypeLoadException.

 

在Visual Studio的SDK Command Prompt中运行fuslogvw.exe.

 

Assembly Binding Log Viewer (Fuslogvw.exe)

http://msdn.microsoft.com/en-us/library/e74a18c4%28VS.71%29.aspx 

Assembly Binding Log Viewer (Fuslogvw.exe)

http://msdn.microsoft.com/en-us/library/e74a18c4%28VS.80%29.aspx

posted @ 2010-02-05 17:09 中道学友 阅读(204) 评论(0) 编辑

IIS Metabase.xml在修改过了之后一定要IISRESET

如题.

posted @ 2010-02-05 14:38 中道学友 阅读(88) 评论(0) 编辑

SharePoint中的Event Receivers 之一 Event Receiver基础

Event Receivers代表着一种开发扩展能力的机制, 通过它可以为列表和列表项等元素添加行为. Event Receiver是一个类, 包含一个或多个叫做"event handler"的, 被WSS自动执行的方法, 这些方法会响应事件, 比如说用户向列表添加一个column, 或者用户删除了一个列表项. Event hannler写好之后, 典型地被用在data validation上, 来确保数据完整性, 或者开启自定义的商业逻辑的处理.

 

被WSS支持的Event可以被分为两个种类: before events 和 after events.

 

before event会在动作执行完成之前被触发. 比如说, 当一个用户试图为列表添加一个新的column的时候, WSS触发一个FieldAdding的事件. 这就是所说的before event, 因为他在field被添加到List之前就触发了, 并且这个事件给了developer一个机会来提供event handler, 可以取消触发时间动作. Before event是在处理请求的thread中用blocking的方式同步地执行的. 正因为如此, before event常常被称为synchronous events.

 

after event不同, 因为它是在动作结束之后才被触发的, 它不提供给开发者机会来取消这个动作. 比如说WSS会触发一个ItemAdded的事件, 在一个Item被添加到列表的时候. 像这样的after event提供给开发者机会去写一个event handler来触发自定义的商业处理, 诸如重新格式化item的一个field的值. 注意, after event是nonblocking的, 因为他们是在另一个thread里异步地执行的. 正因为如此, after events常常被称作asynchronous events.

 

小提示: Event Receiver与WSS2.0中的Event Sink是相等同的概念, 尽管Event receiver能够被应用到任何一种类型的列表上, 而WSS 2.0 中的Event Sink只能应用到基于文档库的列表

 

译:

Inside Microsoft Windows SharePoint Services 3.0

posted @ 2010-02-05 13:51 中道学友 阅读(87) 评论(0) 编辑

C#中的字符串的一些知识点

代码例子请参考原文.

 

1. 字符串是 String 类型的对象,它的值是文本。在内部,这些文本存储为 Char 对象的只读集合,其中每个对象都表示一个以 UTF-16 编码的 Unicode 字符。C# 字符串末尾没有以 null 结尾的字符(这一点与 C 和 C++ 不同),因此 C# 字符串可以包含任意数目的嵌入式 null 字符(“\0”)。字符串长度表示字符数目,无论这些字符是否是由 Unicode 代理项对形成的。若要访问字符串中的各个 Unicode 码位,请使用 StringInfo 对象。

 

2. 在 C# 中,string 关键字是 System.String 的别名。因此,String 与 string 等效,您可以根据自己的喜好选择命名约定。String 类提供了很多用于安全地创建、操作和比较字符串的方法。此外,C# 语言还重载某些运算符来简化常见的字符串操作。有关关键字的更多信息,请参见string(C# 参考)。有关类型及其方法的更多信息,请参见 String

 

3. 注意,除了在使用字符数组初始化字符串时以外,不要使用 new 运算符创建字符串对象。

 

4. 使用 Empty 常量值初始化字符串可新建字符串长度为零的 String 对象。零长度字符串的字符串表示形式为 ""。使用 Empty 值(而不是 null)初始化字符串可以降低发生 NullReferenceException 的可能性。请在尝试访问字符串之前使用静态 IsNullOrEmpty(String) 方法验证字符串的值。

 

5. 字符串对象是不可变的:即它们创建之后就无法更改。所有看似修改字符串的 String 方法和 C# 运算符实际上都以新字符串对象的形式返回结果。在下面的示例中,当连接 s1 和 s2 的内容以形成一个字符串时,不会修改两个原始字符串。+= 运算符会创建一个包含组合内容的新字符串。这个新对象赋给变量 s1,而最初赋给 s1 的对象由于没有其他任何变量包含对它的引用而释放,用于垃圾回收。

 

6. 格式字符串是内容可以在运行时动态确定的一种字符串。采用以下方式创建格式字符串:使用静态 Format 方法并在大括号中嵌入占位符,这些占位符将在运行时替换为其他值。

WriteLine 方法的一个重载将格式字符串用作参数。因此,可以只嵌入格式字符串,而无需显式调用该方法。但若使用 WriteLine 方法在 Visual Studio“输出”窗口中显示调试输出,则必须显式调用 Format 方法,因为 WriteLine 只接受字符串,而不接受格式字符串。有关格式字符串的更多信息,请参见格式化类型

 

7. 空字符串是不包含字符的 System..::.String 对象的实例。在各种编程方案中经常会使用空字符串表示空白文本字段。可以对空字符串调用方法,因为它们是有效的 System..::.String 对象. 相反,null 字符串并不引用 System..::.String 对象的实例,任何对 null 字符串调用方法的尝试都会生成 NullReferenceException。但是,可以在串联和比较操作中将 null 字符串与其他字符串一起使用。

 

8. .NET 中的字符串操作已高度优化,大多数情况下不会显著影响性能。但在某些应用场景中,例如在执行好几百甚至好几千次的紧凑循环中,字符串操作会影响性能。StringBuilder 类创建了一个字符串缓冲区,用于在程序执行大量字符串操作时提供更好的性能。StringBuilder 字符串还使您能够重新分配个别字符(内置字符串数据类型所不支持的字符)。

 

9. 由于 String 类型实现 IEnumerable<(Of <(T>)>),因此可以对字符串使用 Enumerable 类中定义的扩展方法。对于 String 类型,为了避免视觉上的混乱,从 IntelliSense 中排除了这些方法,但这些方法仍然可用。此外,还可以对字符串使用 LINQ 查询表达式。有关更多信息,请参见 LINQ 和字符串

 

原文地址:

http://msdn.microsoft.com/zh-cn/library/ms228362.aspx

posted @ 2010-02-05 11:53 中道学友 阅读(81) 评论(0) 编辑

包含了很多技巧的SharePoint Event Handler的例子

该例子包含的技巧如下:

1. 如何在Event Handler中获取List Item.

2. 如何impersonate另一个用户, 不使用RunWithElevatedPrivilages. 这里进行了包装, 拷贝类, 直接用就可以.

3. 修改一个item的permissions

4. 在web site中创建一个新的permission role

5. 检查一个role是否存在, 这是一个很棒的trick. 读取SPWeb.RoleDefinitions.Xml, 在其中寻找/Role[@Name='" + roleName + "']匹配的节点. 没找到就是没有.

6. 告诉你如何自己写log的小代码例子.

 

using System;
using System.Globalization;
using System.ComponentModel;
using System.IO;
using System.Data;
using System.Text;
using System.Xml;
using System.Collections;
using System.Configuration;
using System.Diagnostics;
using System.Web;
using System.Security;
using System.Security.Policy;
using System.Security.Principal;
using System.Security.Permissions;
using System.Runtime.InteropServices;
using Microsoft.SharePoint;
namespace SharePointTips.SharePoint.Samples.EventHandlers
{
    /// <summary>
    /// This is the event receiver that traps the item added event of the sharepoint list it is attached to.
    /// </summary>
    class ListItemSecuritySetter:SPItemEventReceiver
    {
        #region constants
        /// <summary>
        /// defines the permission set for editors. 
        /// </summary>
        const SPBasePermissions c_EditorPermissions = SPBasePermissions.EditListItems | SPBasePermissions.ViewListItems;
        /// <summary>
        /// defines the permission set for readers
        /// </summary>
        const SPBasePermissions c_ReaderPermissions = SPBasePermissions.ViewListItems;
        /// <summary>
        /// The name of the role that will be created for the author
        /// </summary>
        const string c_AuthorRoleName = "Item Author and Editor";
        /// <summary>
        /// The name of the role that will be created for the reader
        /// </summary>
        const string c_ReaderRoleName = "Item Reader";
        /// <summary>
        /// Debug mode writes almost every action to the file log. In production switch this to false. 
        /// Recommend changing that to read from a configuration file
        /// </summary>
        const bool DEBUG_MODE = true;
        /// <summary>
        /// The page where the log file will be created. Recommend changing that to read from a configuration file
        /// </summary>
        const string c_logFileFolder = @"c:\temp";        
        #endregion

        #region class properties
        /// <summary>
        /// Returns the name of the log file to be used (file name only - not path)
        /// The string returned will contain {0} and {1} that should be replaced with list name and site name.
        /// </summary>
        private string LogFileName
        {
            get
            {
                return "ListItemSecuritySetter-{0}-{1}-" + DateTime.Now.Year.ToString() + 
                    DateTime.Now.Month.ToString() + DateTime.Now.Day.ToString() + ".htm";
            }
        }

        #endregion

        #region local variables

        HTMLFileLogging log;

        #endregion

        #region event handler event trapping
        /// <summary>
        /// The sharepoint event for ItemAdded
        /// </summary>
        /// <param name="properties"></param>
        public override void ItemAdded(SPItemEventProperties properties)
        {
            //run the default event handlers on the item
            base.ItemAdded(properties);


            //create the log handler object
            log = new HTMLFileLogging(c_logFileFolder, 
                string.Format(LogFileName,properties.ListTitle,properties.OpenWeb().Title) , true, false);
                this.WriteToLog("ItemAdded was triggered",true);
            //if in debug mode, write all the properties in the item to the log
            if(DEBUG_MODE)
                WriteItemPropertiesToLog(properties.ListItem);
            
            this.WriteToLog("Setting permissions", true);
            try
            {
                //impersonate an administrator who can change permissions on list items in the list
                ImpersonationUtility imp = ImpersonationUtility.ImpersonateAdmin();
                //open the spweb object to get the token for the user
                using (SPWeb webOrigUser = properties.OpenWeb())
                {
                    //get the token for the impersonation user (this will get the user that the ImpersonationUtility is using)
                    SPUserToken token = webOrigUser.AllUsers[WindowsIdentity.GetCurrent().Name].UserToken;
                    //reopen the spweb object with the new token - full impersonation!
                    using (SPSite site = new SPSite(properties.SiteId, token))
                    {
                        using (SPWeb web = site.OpenWeb(properties.RelativeWebUrl))
                        {

                            //call the function that changes the permissions on the list item. 
                            //Do not use properties.ListItem since that will break impersonation!
                            SetAuthorAsOnlyEditor(web.Lists[properties.ListId].GetItemById(properties.ListItemId));
                        }
                    }
                }

                
            }
            catch (Exception ex)
            {
                this.WriteToLog("Setting permissions encountered an error: " + ex.Message + Environment.NewLine + ex.ToString(), true);
            }
        }
        
        #endregion

        #region custom functions
        /// <summary>
        /// Loops over the item properties and prints them to the log file. should only be called in debug mode!
        /// </summary>
        /// <param name="item">the list item that is currently handled</param>
        private void WriteItemPropertiesToLog(SPListItem item)
        {
            this.WriteToLog("Item Properties:",false);
            foreach(SPField field in item.Fields)
            {
                try
                {
                    this.WriteToLog(field.Title + " : " + item[field.InternalName].ToString(), false);
                }
                catch { }
            }            
        }
        /// <summary>
        /// Function sets the permission on the list item so that the author has edit permission on the item, 
        /// and all other people with access to the document library can only read.
        /// Relies on the values in the constants c_EditorPermissions and c_ReaderPermissions.
        /// </summary>
        /// <param name="item">the list item that is currently handled</param>
        private void SetAuthorAsOnlyEditor(SPListItem item)
        {
            
            using (SPWeb currentWeb = item.Web)
            {
                this.WriteToLog("Getting author from item", true);
                //get the author from the item. 'Author' is a built-in property, so it should be in all lists.
                string authorValue = item["Author"].ToString();                
                SPFieldUserValue authorUserValue = new SPFieldUserValue(currentWeb, authorValue);
                SPUser authorUser = authorUserValue.User;
                this.WriteToLog("Got author name:'" + authorUser.Name + "', email: '" + authorUser.Email + "'", true);
                
                this.WriteToLog("Breaking role inheritance for the item", true);                
                //break the security of the item from the list, but keep the permissions
                item.BreakRoleInheritance(true);
                //change the permissions of everyone with access to this item so they are readers only (c_ReaderPermissions)
                ChangeItemExistingRoles(item);

                this.WriteToLog("Creating role '" + c_AuthorRoleName + "' in the site if needed", true);
                //create a security definition in the web for an author-editor
                SPRoleDefinition def = CreateRoleInSite(currentWeb,c_AuthorRoleName,c_EditorPermissions);
                this.WriteToLog("Assigning role to the user", true);
                //Set the author user with the permissions defined
                SPRoleAssignment authorRole = new SPRoleAssignment(authorUser.LoginName, 
                    authorUser.Email, authorUser.Name, authorUser.Notes);
                this.WriteToLog("Binding the role assignment of the user to the definition", true);
                authorRole.RoleDefinitionBindings.Add(def);
                this.WriteToLog("Adding the role to the item", true);
                item.RoleAssignments.Add(authorRole);
                this.WriteToLog("Updating the item", true);
                item.Update();
                this.WriteToLog("Success!", true);
            }
        }
        /// <summary>
        /// This function will make everyone with access to the item a reader.
        /// Loops over all the roles that exist in the item, removes the bindings and adds the reader permission definition to them
        /// </summary>
        /// <param name="item">the list item currently handled</param>
        private void ChangeItemExistingRoles(SPListItem item)
        {
            //get, and if necessary create, the reader role
            SPRoleDefinition readerDef = CreateRoleInSite(item.Web, c_ReaderRoleName, c_ReaderPermissions);

            
            foreach (SPRoleAssignment roleAssignment in item.RoleAssignments)
            {
                //delete the existing permissions
                roleAssignment.RoleDefinitionBindings.RemoveAll();
                //add the reader permission
                roleAssignment.RoleDefinitionBindings.Add(readerDef);
                roleAssignment.Update();
                item.Update();

            }
        }
        /// <summary>
        /// Gets and if necessary creates the role in the site.
        /// </summary>
        /// <param name="web">The site where the role should be created</param>
        /// <param name="roleName">The name of the role to create</param>
        /// <param name="permissions">The permission set to give the role. Example: 
        /// SPBasePermissions.EditListItems | SPBasePermissions.ViewListItems</param>
        /// <returns></returns>
        private SPRoleDefinition CreateRoleInSite(SPWeb web,string roleName,SPBasePermissions permissions)
        {
            this.WriteToLog("Checking if role '"+roleName+"' exists in the web", true);
            //check that the role exists
            if (RoleExists(web, roleName))
            {
                this.WriteToLog("Role exists in the web", true);
                //role exists - return it
                return web.RoleDefinitions[roleName];
            }
            else
            {
                //role does not exist in the site-  create it and return.
                this.WriteToLog("Role does not exist in the web. creating a new role", true);
                //Create the role definition in the web by the name specified in c_AuthorRoleName
                SPRoleDefinition def = new SPRoleDefinition();
                def.BasePermissions = permissions;
                def.Name = roleName;
                this.WriteToLog("Adding the role to the FirstUniqueRoleDefinitionWeb", true);
                web.FirstUniqueRoleDefinitionWeb.RoleDefinitions.Add(def);
                this.WriteToLog("Updating the web", true);
                web.FirstUniqueRoleDefinitionWeb.Update();
                web.FirstUniqueRoleDefinitionWeb.Dispose();
                this.WriteToLog("Reopening the current web object", true);
                web = web.Site.OpenWeb();
                this.WriteToLog("Verifying role is in current web", true);
                if (RoleExists(web, roleName))
                    return web.RoleDefinitions[roleName];
                else
                {
                    throw new Exception("Role does not exist?");
                }

            }
        }
        /// <summary>
        /// This function checks the spweb objec to see if a specific role exists (by name)
        /// </summary>
        /// <param name="web">the spweb object for the site to contain the role.</param>
        /// <param name="roleName">the name of the role searched for</param>
        /// <returns></returns>
        private bool RoleExists(SPWeb web, string roleName)
        {
            this.WriteToLog("Loading the RoleDefinitions xml string:", true);
            this.WriteToLog(web.RoleDefinitions.Xml, true);
            //read the xml of the roledefinitions
            XmlDocument doc = new XmlDocument();
            doc.LoadXml(web.RoleDefinitions.Xml);
            this.WriteToLog("Searching for the role in the xml", true);
            //search for the role with the name in the xml
            XmlNode node = doc.SelectSingleNode("//Role[@Name='"+roleName+"']");
            //if the search returned null, the role does not exist
            if (node == null)
                return false;
            else
                return true;
        }
        /// <summary>
        /// writes a message to the log file
        /// </summary>
        /// <param name="message">The message to write</param>
        /// <param name="debugOnly">If true, the message will only get written when the code runs in debug mode.</param>
        private void WriteToLog(string message,bool debugOnly)
        {
            if (DEBUG_MODE || !debugOnly)
                log.WriteToLogFile(message);            
        }
        #endregion
    }
    /// <summary>
    /// Handles simple file logging. Recommend switching to trace log.
    /// </summary>
    class HTMLFileLogging
    {
        #region class properties
        private string logFolderPath = @"c:\logs";
        public string LogFolderPath
        {
            get
            {
                return logFolderPath;
            }
            set
            {
                if (Directory.Exists(value))
                {
                    logFolderPath = value;
                    if (logFolderPath.EndsWith("\\"))
                    {
                        logFolderPath = logFolderPath.Remove(logFolderPath.Length);
                    }
                }
                else
                {
                    throw new DirectoryNotFoundException();
                }
            }
        }
        private string logFileName = "";
        public string LogFileName
        {
            get
            {
                return logFileName;
            }
            set
            {
                logFileName = value;
            }
        }
        public string LogFilePath
        {
            get
            {
                return this.LogFolderPath + "\\" + this.LogFileName;
            }
        }
        
        #endregion
        
        #region CTOR
        /// <summary>
        /// Create a HTMLFileLogging object
        /// </summary>
        /// <param name="folderPath">The path of the folder that will hold the log file (no file name)</param>
        /// <param name="fileName">The name of the file to create</param>
        /// <param name="createPath">When this is set to true and the folder does not exist, the code will create the folder.</param>
        /// <param name="deleteFile">When this is set to true and the file exists, the code will delete the file and create a new one</param>
        public HTMLFileLogging(string folderPath, string fileName, bool createPath, bool deleteFile)
        {
         
            this.LogFileName = fileName;
            
            if (createPath && !Directory.Exists(folderPath))
            {
                Directory.CreateDirectory(folderPath);
            }
            this.LogFolderPath = folderPath;
            if (File.Exists(this.LogFilePath) && deleteFile)
            {
                File.Delete(this.LogFilePath);
            }

        }

        #endregion

        #region custom code
        /// <summary>
        /// Writes a string to the log file. 
        /// </summary>
        /// <param name="message">a string to write. supports html tags.</param>
        public void WriteToLogFile(string message)
        {
            try
            {
                StreamWriter sw = new StreamWriter(this.LogFilePath,true);
                sw.WriteLine("<p>");
                sw.WriteLine("<date>" + DateTime.Now.ToShortDateString()+ "</date> <time>" + 
                    DateTime.Now.ToLongTimeString() + 
                    "</time> <br /> <message>" + message + "</message>");
                sw.WriteLine("</p>");
                sw.Flush();
                sw.Close();
            }
            catch (Exception ex)
            {
            }
        }

        #endregion

    }
    /// <summary>
    /// Thanks to impersonation example of Victor Vogelpoel [Macaw] 
    /// http://dotnetjunkies.com/WebLog/victorv/archive/category/2032.aspx
    /// </summary>
    public sealed class ImpersonationUtility
    {        
        private static string ADMINDOMAINACCOUNT = @"domain\user";//CHANGE THIS!
        private static string ADMINDOMAIN = "domain";//CHANGE THIS!
        private static string ADMINACCOUNT = "user";//CHANGE THIS!
        private static string ADMINPASSWORD = "password";//CHANGE THIS!
        private WindowsImpersonationContext _wiContext;
        public IntPtr token;
        /// <summary>
        /// Private ctor.
        /// </summary>
        private ImpersonationUtility()
        { }
        /// <summary>
        /// Start impersonating the administrator.
        /// </summary>
        /// <returns>an ImpersonationUtility instance.</returns>
        public static ImpersonationUtility ImpersonateAdmin()
        {
            ImpersonationUtility imp = new ImpersonationUtility();
            imp._ImpersonateAdmin();
            return imp;
        }
        /// <summary>
        /// Undo the impersonation.
        /// </summary>
        public void Undo()
        {
            if (this._wiContext != null)
            {
                this._wiContext.Undo();
                this._wiContext = null;
            }
        }
        private void _ImpersonateAdmin()
        {
            token = IntPtr.Zero;
            IntPtr tokenDuplicate = IntPtr.Zero;
            try
            {
                // Only start admin impersonation if we're not the admin...
                if (String.Compare(ADMINDOMAINACCOUNT, WindowsIdentity.GetCurrent().Name, true, CultureInfo.InvariantCulture) != 0)
                {
                    // Temporarily stop the impersonation started by Web.Config.
                    // WindowsIdentity.Impersonate() will store the current identity (the
                    // account of the requestor) and return to the account of the ApplicationPool
                    // which is "DOMAIN\SPAdmin".
                    this._wiContext = WindowsIdentity.Impersonate(IntPtr.Zero);
                    // But somehow the reverted account "DOMAIN\SPAdmin" still does
                    // not have enough privileges to access SharePoint objects, so
                    // we're logging in DOMAIN\SPAdmin again...
                    if (NativeMethods.LogonUserA(ADMINACCOUNT, ADMINDOMAIN, ADMINPASSWORD,
                        NativeMethods.LOGON32_LOGON_INTERACTIVE,
                        NativeMethods.LOGON32_PROVIDER_DEFAULT, ref token) != 0)
                    {
                        if (NativeMethods.DuplicateToken(token, 2, ref tokenDuplicate) != 0)
                        {
                            WindowsIdentity wi = new WindowsIdentity(tokenDuplicate);
                            // NOTE: Impersonate may fail if account that tries to impersonate does
                            // not hold the "Impersonate after Authentication" privilege
                            // See local security policy - user rights assignment.
                            // Note that the ImpersonationContext from the Impersonate() call
                            // is ignored. Upon the Undo() call, the original account
                            // will be reinstated.
                            wi.Impersonate();
                        }
                        else
                        {
                            throw new Win32Exception(Marshal.GetLastWin32Error(),
                            "Impersonation: Error duplicating token after logon for user \"DOMAIN\\SPAdmin\"");
                        }
                    }
                    else
                    {
                        throw new Win32Exception(Marshal.GetLastWin32Error(),
                        "Impersonation: Error logging on user \"DOMAIN\\SPAdmin\"");
                    }
                }
            }
            finally
            {
                if (token != IntPtr.Zero)
                    NativeMethods.CloseHandle(token);
                if (tokenDuplicate != IntPtr.Zero)
                    NativeMethods.CloseHandle(tokenDuplicate);
            }
        }
    }
    /// <summary>
    /// Thanks to impersonation example of Victor Vogelpoel [Macaw] 
    /// http://dotnetjunkies.com/WebLog/victorv/archive/category/2032.aspx
    /// </summary>
    internal sealed class NativeMethods
    {
        private NativeMethods() { }

        [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
        public static extern bool CloseHandle(IntPtr handle);

        public const int LOGON32_PROVIDER_DEFAULT = 0;
        public const int LOGON32_LOGON_INTERACTIVE = 2;
        public const int LOGON32_LOGON_NETWORK = 3;

        [DllImport("advapi32.dll")]
        public static extern int LogonUserA(String lpszUserName,
        String lpszDomain,
        String lpszPassword,
        int dwLogonType,
        int dwLogonProvider,
        ref IntPtr phToken);

        [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        public static extern int DuplicateToken(IntPtr hToken,
        int impersonationLevel,
        ref IntPtr hNewToken);


        [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        public static extern bool RevertToSelf();
    } 

 

摘自:

Sample Event Handler to set Permissions

http://www.sharepoint-tips.com/2007/03/sample-event-handler-to-set-permissions.html

posted @ 2010-02-05 11:48 中道学友 阅读(449) 评论(0) 编辑

@在C# String的使用

1. C# 中 字符串常量可以以 @ 开头声名,这样的优点是转义序列“不”被处理,按“原样”输出,即我们不需要对转义字符加上 (反斜扛),就可以轻松coding。如
string filePath = @"c:DocsSourcea.txt"; // rather than "c:DocsSourcea.txt"


2. 如要在一个用 @ 引起来的字符串中包括一个双引号,就需要使用两对双引号了。
这时候你不能使用 来转义双引号了,因为在这里 的转义用途已经被 @ “屏蔽”掉了。如
@"""Ahoy!"" cried the captain."; // 输出为: "Ahoy!" cried the captain.

有点像SQL中的单引号常量处理方式:
DECLARE @msg varchar(100)
SET @msg = ''Ahoy!'' cried the captain.' -- 输出为: 'Ahoy!' cried the captain.

 

3. @ 会识别换行符
其实这个特性,我不知道怎么描述,只是偶然发现的,先看下面的代码吧:
string script = @"
            <script type=""type/javascript"">
            function doSomething()
            {
            }
            </script>";

 

在cs文件中写js,结构就很清晰了,正常情况我们是这样coding的:
string script2 = "<script type="type/javascript">function doSomething(){}</script>";
// or
string script3 =
            "<script type="type/javascript">" +
            "function doSomething(){ " +
            "}</script>";


通常我们会选择后者,因为js代码一般比较长,或者方法体很大,或者需要连接其他变量,这样结构比较清晰。
注意:如果“拼接”的次数很多,应该考虑使用StringBuilder了,有助于提高性能。
还有一种场景,也很常见,在程序中拼接 SQL 语句,如
private const string SQL_INS_USER = @"
            INSERT INTO t_User([UserName], [Password], Email)
                        VALUES(@UserName, @Password, @Email)";

然而,我们需要关注一个问题:字符串长度
看下面的测试代码:
private const string SQL_INS_USER1 = @"
        INSERT INTO t_User([UserName], [Password], Email)
                    VALUES(@UserName, @Password, @Email)";
private const string SQL_INS_USER2 = @"INSERT INTO t_User([UserName], [Password], Email)
                    VALUES(@UserName, @Password, @Email)";

private const string SQL_INS_USER3 = @"INSERT INTO t_User([UserName], [Password], Email)
                                     VALUES(@UserName, @Password, @Email)";

static void Main(string[] args)
{
    Console.WriteLine(SQL_INS_USER1.Length); // 126
    Console.WriteLine(SQL_INS_USER2.Length); // 112
    Console.WriteLine(SQL_INS_USER3.Length); // 86
}

可以看到三个字符串长度分别相差了,14=126-112和26=112-86,在代码编辑器中,SQL_INS_USER1
中第一个换行符号之后,缩进13个空格(INSERT之前),而
SQL_INS_USER2 中第一个换行符号之后,缩进25个空格(VALUES之前),
那么,加上一个换行符,刚刚好 14和26

如此编写代码,虽然提高了代码的清晰度和简便性,却无行中带来了另一个问题:字符长度!
很多场景下我们希望字符串越短越好,如,通过ADO.NET 发送 SQL 语句给数据库执行。
所以还是慎用之!

 

引自:

http://space.baidu.com/jy02206644/blog/item/e311c6cf0478e130b700c8d5.html

posted @ 2010-02-05 11:46 中道学友 阅读(37) 评论(0) 编辑

internal class in C#

The internal keyword is an access modifier for types and type members. Internal members are accessible only within files in the same assembly.

 

A common use of internal access is in component-based development because it enables a group of components to cooperate in a private manner without being exposed to the rest of the application code. For example, a framework for building graphical user interfaces could provide Control and Form classes that cooperate using members with internal access. Since these members are internal, they are not exposed to code that is using the framework.

 

It is an error to reference a member with internal access outside the assembly within which it was defined.

Caution   An internal virtual method can be overridden in some languages, such as textual Microsoft intermediate language (MSIL) using Ilasm.exe, even though it cannot be overridden using C#.

 

Example

This example contains two files, Assembly1.cs and Assembly2.cs. The first file contains an internal base class, BaseClass. In the second file, an attempt to access the member of the base class will produce an error.

File Assembly1.cs:

// Assembly1.cs
// compile with: /target:library
internal class BaseClass 
{
   public static int IntM = 0;
}

File Assembly2.cs

// Assembly2.cs
// compile with: /reference:Assembly1.dll
// CS0122 expected
class TestAccess 
{
   public static void Main() 
   {
      BaseClass myBase = new BaseClass();   // error, BaseClass not visible outside assembly
   }
}

 

 

http://msdn.microsoft.com/en-us/library/7c5ka91b(VS.71).aspx

posted @ 2010-02-05 11:11 中道学友 阅读(838) 评论(0) 编辑

Sealed Class in C#

Sealed classes are used to restrict the inheritance feature of object oriented programming. Once a class is defined as sealed class, this class cannot be inherited.

 

In C#, the sealed modifier is used to define a class as sealed. In Visual Basic .NET, NotInheritable keyword serves the purpose of sealed. If a class is derived from a sealed class, compiler throws an error.

 

If you have ever noticed, structs are sealed. You cannot derive a class from a struct. 

 

http://www.c-sharpcorner.com/UploadFile/mahesh/SealedClasses11142005063733AM/SealedClasses.aspx

posted @ 2010-02-05 11:07 中道学友 阅读(184) 评论(0) 编辑

WebDAV

Web Distributed Authoring and Versioning (WebDAV) 扩展了HTTP/1.1协议, 允许客户端publich, lock, 和管理在web上的资源.

 

与IIS集成之后, WebDAV允许客户端进行下列操作

  • 在你的服务器的WebDAV publishing directory上操纵资源. 比如说, 指派了正确权限的用户能够在WebDAV目录中拷贝和移动文件.
  • 修改与这些资源相关的属性. 比如说一个用户可以写入或读取文件的属性信息.
  • 锁, 或解锁资源, 这样多个用户可以并发地读取文件. 然而, 一次只有一个用户可以修改这个文件.
  • 在WebDAV目录下搜索文件的内容和属性.
  •  

    摘自:

    About WebDAV

    http://technet.microsoft.com/en-us/library/cc781730(WS.10).aspx

    posted @ 2010-02-05 10:33 中道学友 阅读(46) 评论(0) 编辑

    UNC - Microsoft Windows

    定义

    ========

    UNC是一种命名惯例, 主要用于在Microsoft Windows上指定和映射网络驱动器. UNC命名惯例最多被应用于在局域网中访问文件服务器或者打印机

     

    UNC命名语法

    ========

    UNC命名使用特定的标记法来识别网络资源. UNC命名由三个部分组成- 服务器名, 共享名, 和一个可选的文件路径. 这三个部分通过backslash连接起来, 如下:

    \\server\share\file_path

     

    这里的server部分引用的是由DNS或者WINS网络服务维护的字符串. 服务器名是由system administrator设定的.

     

    share部分引用了由系统管理员创建的一个label. 在绝大多数版本的windows中, 比如说, 共享名admin$指的是操作系统安装的根路径(通常是C:\WINNT 或 C:\WINDOWS).

     

    file部分引用在共享点之下的本地子文件夹.

     

    UNC命名实例

    ========

  • \\teela\admin$ (to reach C:\WINNT)
  • \\teela\admin$\system32 (to reach C:\WINNT\system32)
  • \\teela\temp (to reach C:\temp)
  •  

    通过使用Windows Exlorer或者DOM命令行, 再加上恰当的安全证明, 你可以通过指定UNC名字来映射网络驱动器, 远程地访问一台计算机上的文件夹.

     

    http://compnetworking.about.com/od/windowsnetworking/g/unc-name.htm

    posted @ 2010-02-05 10:16 中道学友 阅读(174) 评论(0) 编辑

    导航

    <2010年2月>
    31123456
    78910111213
    14151617181920
    21222324252627
    28123456
    78910111213

    公告

    若需了时直需了,若觅了时无了时。

    世界上只有一种失败, 那就是半途而废.

    个人介绍

    博主专注SharePoint以及与之相关的微软产品与技术. 现就职于微软公司全球技术支持中心, 为分布于东南亚及澳洲企业级客户提供技术支持.


    联系方式

    邮箱:

    ylongzhang@hotmail.com

    新浪微博:

    http://weibo.com/awpatp


    访问分布

    Locations of visitors to this page 免费计数器申请
    blog计数器
    昵称:中道学友
    园龄:3年8个月
    粉丝:31
    关注:2

    搜索

     

    随笔分类(811)

    随笔档案(812)

    常用内容

    工具箱

    阅读排行榜

    推荐排行榜

    技术追求准确,态度积极向上