zoukankan      html  css  js  c++  java
  • 在自己的代码中获取SharePoint的存储占用情况

    如果我们想要关注SharePoint网站中的存储使用情况的话,SharePoint中可以使用spSite.Usage获取当前网站集的存储占用情况(这是一个名为UsageInfo的结构,它的Storage属性就是网站集占用的字节数)。

    但是通过这种方法我们只能得到网站集的存储使用情况,无法得到更细粒度比如网站、文档库、文件夹使用了多少存储空间(需要注意的是,一个文件所占用的存储空间不一定是这个文件的大小,如果你开启了版本控制的话,那么所有的版本都应该计算到占用的存储空间中)。

    在SharePoint 2010 SP1中,新增了一个叫Storage Metric的功能(中文版不恰当地翻译成了“存储标准”),可以看到网站集中每一级别所使用的存储空间(详细介绍可以参考我之前写过的这篇Blog:SharePoint 2010 SP1新功能(存储标准))。

    但遗憾的是,这个新增功能的涉及到的所有代码都是internal的,它在数据库里新增的两个表结构都很简单,但是那个存储过程比较复杂,也很难直接从这个方法去获取,因此,就只剩下了一个选择:反射。

    通过反射的方法,我们可以调用SPSite中的内部方法GetStorageMetrics,它会返回一个SPStorageMetricsResult的类,里面的Children属性中是一个List<SPStorageMetricItem>,这一些东西都是internal的,但都可以通过反射来获取到。

    我为SPSite扩展了一个同名的方法GetStorageMetrics,实现这个功能,完整的代码如下(单独的cs文件下载点我点我):

       1: using System;
       2: using System.Collections;
       3: using System.Collections.Generic;
       4: using System.Linq;
       5: using System.Reflection;
       6: using System.Text;
       7: using Microsoft.SharePoint;
       8:  
       9: namespace Erucy.Utilities
      10: {
      11:     public class SPStorageMetricItem
      12:     {
      13:         public enum MetricType
      14:         {
      15:             Invalid = -1,
      16:             File = 0,
      17:             Folder = 1,
      18:             Web = 2
      19:         }
      20:  
      21:         public string DisplayName { get; private set; }
      22:         public Guid Id { get; private set; }
      23:         public DateTime LastModified { get; private set; }
      24:         public long? TotalSize { get; private set; }
      25:         public MetricType Type { get; private set; }
      26:         public string Url { get; private set; }
      27:         public Guid WebId { get; private set; }
      28:  
      29:         public SPStorageMetricItem(object metricObj)
      30:         {
      31:             this.DisplayName = (string)GetPropValue(metricObj, "DisplayName");
      32:             this.Id = (Guid)GetPropValue(metricObj, "Id");
      33:             this.LastModified = (DateTime)GetPropValue(metricObj, "LastModified");
      34:             this.TotalSize = (long?)GetPropValue(metricObj, "TotalSize");
      35:             this.Url = (string)GetPropValue(metricObj, "Url");
      36:             this.WebId = (Guid)GetPropValue(metricObj, "WebId");
      37:  
      38:             string itemType = Convert.ToString(GetPropValue(metricObj, "Type"));
      39:             switch (itemType)
      40:             {
      41:                 case "File":
      42:                     this.Type = MetricType.File;
      43:                     break;
      44:                 case "Folder":
      45:                     this.Type = MetricType.Folder;
      46:                     break;
      47:                 case "Web":
      48:                     this.Type = MetricType.Web;
      49:                     break;
      50:                 default:
      51:                     this.Type = MetricType.Invalid;
      52:                     break;
      53:             }
      54:         }
      55:  
      56:         private object GetPropValue(object obj, string propertyName)
      57:         {
      58:             PropertyInfo propInfo = obj.GetType().GetProperty(propertyName,
      59:                 BindingFlags.GetProperty | BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.ExactBinding);
      60:             return propInfo.GetValue(obj, null);
      61:         }
      62:     }
      63:  
      64:     public static class StorageMetricExtension
      65:     {
      66:         public static List<SPStorageMetricItem> GetStorageMetrics(this SPSite site, string root, int orderBy, bool isAscending)
      67:         {
      68:             MethodInfo getMetricMethod = typeof(SPSite).GetMethod("GetStorageMetrics", 
      69:                 BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.ExactBinding);
      70:             object metricResultObj = getMetricMethod.Invoke(site, new object[] { root, orderBy, isAscending });
      71:  
      72:             PropertyInfo childrenProperty = metricResultObj.GetType().GetProperty("Children", 
      73:                 BindingFlags.GetProperty | BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.ExactBinding);
      74:             IList rawMetricItems = childrenProperty.GetValue(metricResultObj, null) as IList;
      75:  
      76:             List<SPStorageMetricItem> result = new List<SPStorageMetricItem>(rawMetricItems.Count);
      77:             foreach (object metricObj in rawMetricItems)
      78:             {
      79:                 result.Add(new SPStorageMetricItem(metricObj));
      80:             }
      81:             return result;
      82:         }
      83:     }
      84: }

    其中的SPStorageMetricItem类和SharePoint内置的那个internal类基本上是一致的,可以获取到相关的信息,包括:

    • DisplayName:名称
    • Url:Url地址
    • LastModified:最后修改时间
    • Id:对象的Guid(如果对象是网站/列表的话,这个Id并不是网站/列表ID,而是他们的根文件夹的ID)
    • WebId:所在网站的Id
    • Type:类型,包括网站、文件夹、文件
    • TotalSize:对象占用的存储空间,以字节为单位

    在使用的时候很简单,有三个参数:

    • root:根路径,方法会返回这个路径中所有子网站和子文件夹、文件所占用的大小空间,使用相对服务器的路径
    • orderBy:排序(这个原本是一个internal的枚举,我就偷懒直接用int了),0是按照TotalSize排序,1是按照LastModified排序
    • isAscending:正序或逆序

    这个在使用的过程中会有如下几个需要考虑的问题:

    1、因为使用了反射,所以速度会有点慢

    2、必须是SharePoint 2010 SP1以及之后的版本(因为功能是在SP1才有的)

    3、如果root参数不是网站的话(比如你想获取一个文档库中若干文件夹占用的存储空间),运行在非IIS进程中的时候会报错。这个和SharePoint底层那个COM的实现有关,没什么解决办法。

  • 相关阅读:
    vscode git
    ionic2/cordova自定义插件集成aar包
    ui-router实现返回上一页功能
    《深入理解Spark:核心思想与源码分析》一书正式出版上市
    记一次Web服务的性能调优
    程序设计——冲突
    Oracle执行计划的查看
    程序设计——规则
    Tomcat源码分析——Session管理分析(下)
    Tomcat源码分析——Session管理分析(上)
  • 原文地址:https://www.cnblogs.com/erucy/p/2526611.html
Copyright © 2011-2022 走看看