从完整网址获取列表名称

时间:2015-04-01 21:39:09

标签: file sharepoint download csom

我有数百个不同的随机URL,lib中的所有文档,没有来自不同农场和不同网站集和网站的任何其他参数,目标是从SharePoint下载文件作为二进制数组。

所以,例如收到的网址= http://a.b.c.d.e/f.g/h.i/j/k/l/m.docx

那么如何获得(a)正确的网站集根网址(b)网站根网址(c)库根网址呢?我现在想到的唯一方法是慢慢剥离网址的每个部分,直到例如.Rootfolder不再提供异常......或者反过来通过url的第一部分缓慢添加位,直到rootfolder nog longers给出异常然后查询子网站等。

2 个答案:

答案 0 :(得分:3)

关键是ClientContext constructor只接受网站/网站的网址。 但是如果url将以下列格式指定:

http://site/web/documents/file.docx

然后会发生异常System.Net.WebException

以下示例演示了如何从请求Url解析ClientContext

public static class ClientContextUtilities
{
    /// <summary>
    /// Resolve client context  
    /// </summary>
    /// <param name="requestUri"></param>
    /// <param name="context"></param>
    /// <param name="credentials"></param>
    /// <returns></returns>
    public static bool TryResolveClientContext(Uri requestUri, out ClientContext context, ICredentials credentials)
    {
        context = null;
        var baseUrl = requestUri.GetLeftPart(UriPartial.Authority);
        for (int i = requestUri.Segments.Length; i >= 0; i--)
        {
            var path = string.Join(string.Empty, requestUri.Segments.Take(i));
            string url = string.Format("{0}{1}", baseUrl, path);
            try
            {
                context = new ClientContext(url);
                if (credentials != null)
                    context.Credentials = credentials;
                context.ExecuteQuery();
                return true;
            }
            catch (Exception ex) {}
        }
        return false;
    }

}

<强>用法

ClientContext context;
if (ClientContextUtilities.TryResolveClientContext(requestUri, out context, null))
{
     using (context)
     {
         var baseUrl = requestUri.GetLeftPart(UriPartial.Authority);
         var fileServerRelativeUrl = requestUri.ToString().Replace(baseUrl, string.Empty);                  
         var file = context.Web.GetFileByServerRelativeUrl(fileServerRelativeUrl);
         context.Load(file); 
         context.Load(context.Web);
         context.Load(context.Site);
         context.ExecuteQuery();
     }
}

由于您的目标是下载文件,因此可以通过非常直接的方式完成它而无需解析网址部分。

例如,使用WebClient.DownloadFile Method

private static void DownloadFile(Uri fileUri, ICredentials credentials, string localFileName)
{
     using(var client = new WebClient())
     {
        client.Credentials = credentials;
        client.DownloadFile(fileUri, localFileName);
     }  
}

答案 1 :(得分:0)

我已经制定了一种工作方法,但它似乎很精细,所以任何改进建议都欢迎“下载文件,如果其中一个特定列有价值”是“

public void getDocument(Document doc)
    {
        // get the filename
        Uri uri = new Uri(doc.uri);
        doc.filename = "";
        doc.filename = System.IO.Path.GetFileName(uri.LocalPath);
        //string fullPathWithoutFileName = docUri.Replace(filename, "");
        // would also include ?a&b so:           
        string[] splitDocUri = doc.uri.Split('/');
        string fullPathWithoutFileName = "";
        for (int i = 0; i < splitDocUri.Length -1; i++)
        {
            fullPathWithoutFileName += (splitDocUri[i] + '/');
        }

        // get via "_api/contextinfo" the context info
        HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(fullPathWithoutFileName + "_api/contextinfo");
        req.Method = "POST";
        req.Accept = "application/json; odata=verbose";
        req.Credentials = new NetworkCredential(doc.username, doc.password, doc.domain);
        req.Headers.Add("X-FORMS_BASED_AUTH_ACCEPTED","f");
        req.ContentLength = 0;
        BypassCertificateError();
        HttpWebResponse rp = (HttpWebResponse)req.GetResponse();
        Stream postStream = rp.GetResponseStream();
        StreamReader postReader = new StreamReader(postStream);
        string results = postReader.ReadToEnd();
        // Now parse out some values needs system.web.extensions
        JavaScriptSerializer jss = new JavaScriptSerializer();
        var d = jss.Deserialize<dynamic>(results);
        string formDigestValue = d["d"]["GetContextWebInformation"]["FormDigestValue"];
        // the full url to the website e.g. "http://server:7777/level1/level 2"     
        string webFullUrl = d["d"]["GetContextWebInformation"]["WebFullUrl"];
        // the full url to the site collection e.g.       "http://server:7777"
        string siteFullUrl = d["d"]["GetContextWebInformation"]["SiteFullUrl"];

        // now we can create a context
        ClientContext ctx = new ClientContext(webFullUrl);
        ctx.ExecutingWebRequest +=
          new EventHandler<WebRequestEventArgs>(ctx_MixedAuthRequest);
        BypassCertificateError();
        ctx.AuthenticationMode = ClientAuthenticationMode.Default;
        ctx.Credentials = new NetworkCredential(doc.username, doc.password, doc.domain);

        // Get the List
        Microsoft.SharePoint.Client.File file = ctx.Web.GetFileByServerRelativeUrl(uri.AbsolutePath);
        List list = file.ListItemAllFields.ParentList;
        ctx.Load(list);
        ctx.ExecuteQuery();

        // execute a CAML query against it
        CamlQuery camlQuery = new CamlQuery();
        camlQuery.ViewXml =
            "<View><Query><Where><Eq><FieldRef Name='FileLeafRef'/>" +
            "<Value Type='Text'>" + doc.filename + "</Value></Eq></Where>" +
            "<RowLimit>1</RowLimit></Query></View>";
        ListItemCollection listItems = list.GetItems(camlQuery);
        ctx.Load(listItems);
        try {
            ctx.ExecuteQuery();
        }
        catch
        {
            // e.g. : no access or the listname as incorrectly deduced
            throw;
        }

        // and now retrieve the items needed
        if (listItems.Count == 1)
        {
            ListItem item = listItems[0];
            // some more checking from testColumn to decide if to download yes/no
            string testColumn;
            if (item.IsPropertyAvailable("testColumn")) {
                testColumn = (string)item["testColumn"];
            }

            FileInformation fileInformation =
                Microsoft.SharePoint.Client.File.OpenBinaryDirect(ctx,
                    (string)item["FileRef"]);
            doc.bytes = ReadFully(fileInformation.Stream);

        }
        else
        {
            doc.errormessage = "Error: No document found";
        }

    }
相关问题