从CalDAV获取用户的日历列表

时间:2012-07-24 00:24:12

标签: c# webdav caldav

我正在尝试从CalDAV服务器获取当前用户拥有的日历列表。

我能够使用我们的初始测试帐户获取此信息,并提供以下请求:

PROPFIND /calendars/users/test/
<propfind xmlns='DAV:'>
    <allprop/>
</propfind>

结果是<multistatus>元素,其中包含多个<response>元素。如果我提取resourcetype是日历的元素,我会得到我的日历列表。

但是,当我们添加其他用户时,会产生“Not Found”错误,因此我使用“Principal match”请求来获取当前用户的“calendar-home-set”路径。

该路径看起来像/ d817aaec-7d24-5b38-bc2f-6369da72cdd9 /。所以我用这条路径尝试了上述请求。现在结果是<multistatus>元素,只有一个<response>元素。它不包含任何日历。第一个响应与我原始请求中的第一个响应完全相同。

我不能为我的生活找出能让我在所有情况下获得用户日历列表的魔法酱。

修改

这是我的一些代码。我最初尝试过的“/ calendars / users / test /”网址是从GetRequestAddress()返回的。我的第二个案例,我使用principal-match来获取使用CalendarHomeSet的日历路径(均显示如下)。

Headers["Depth"] = "1";
//XElement xmlResult = UploadXml(GetRequestAddress(), // Alternatively, CalendarHomeSet
    method: CalDavMethod.PropertyFind,
    xml: XDocument.Parse("<propfind xmlns='DAV:'>" +
        "<allprop/>" +
        "</propfind>").Root);

private string GetRequestAddress(string calendarHRef = null, string resource = null)
{
    string path = calendarHRef;
    if (String.IsNullOrWhiteSpace(path))
        path = String.Format("/calendars/users/{0}/", UserName);
    if (!String.IsNullOrWhiteSpace(resource))
        path = Path.Combine(path, resource);
    return path;
}

/// <summary>
/// Gets/sets the path to the parent folder of any calendar subfolders
/// owned by the current user.
/// </summary>
public string CalendarHomeSet
{
    get
    {
        if (calendarHomeSet == null)
        {
            Headers["Depth"] = "0";

            XElement xmlResult = UploadXml(String.Format("/principals/users/{0}/", UserName),
                method: "REPORT",
                xml: XDocument.Parse(XmlHeader +
                    "<D:principal-match xmlns:D=\"DAV:\">" +
                        "<D:self/>" +
                        "<D:prop>" +
                            "<C:calendar-home-set xmlns:C=\"urn:ietf:params:xml:ns:caldav\"/>" +
                        "</D:prop>" +
                    "</D:principal-match>").Root);
            //
            XElement el = xmlResult.Descendants(CalDavXmlns + "calendar-home-set").FirstOrDefault();
            if (el != null)
            {
                calendarHomeSet = (string)el;
                if (!calendarHomeSet.EndsWith("/"))
                    calendarHomeSet += '/';
            }
        }
        return calendarHomeSet;
    }

    set
    {
        calendarHomeSet = value;
    }
}

private string calendarHomeSet = null;

第二次编辑:

以下是有关我的请求和回复的确切内容的更多详细信息。在第一个中,请注意结果包括一个集合,后跟两个日历集合。

PROPFIND /calendars/users/test/

<propfind xmlns="DAV:">
  <allprop />
</propfind>

响应:

<multistatus xmlns="DAV:">
  <response>
    <href>/calendars/users/test/</href>
    <propstat>
      <prop>
        <getetag>"4293-1000-4FFC9A16"</getetag>
        <current-user-principal>
          <href>/principals/__uids__/d817aaec-7d24-5b38-bc2f-6369da72cdd9/</href>
        </current-user-principal>
        <displayname>Test User</displayname>
        <getcontenttype>httpd/unix-directory</getcontenttype>
        <supportedlock>
          <lockentry>
            <lockscope>
              <exclusive />
            </lockscope>
            <locktype>
              <write />
            </locktype>
          </lockentry>
          <lockentry>
            <lockscope>
              <shared />
            </lockscope>
            <locktype>
              <write />
            </locktype>
          </lockentry>
        </supportedlock>
        <resourcetype>
          <collection />
        </resourcetype>
        <getcontentlength />
        <getlastmodified>Tue, 10 Jul 2012 21:09:42 GMT</getlastmodified>
        <creationdate>2012-07-10T21:09:42Z</creationdate>
        <resource-class xmlns="http://twistedmatrix.com/xml_namespace/dav/">CalendarHomeFile</resource-class>
      </prop>
      <status>HTTP/1.1 200 OK</status>
    </propstat>
  </response>
  <response>
    <href>/calendars/users/test/calendar/</href>
    <propstat>
      <prop>
        <getetag>"42DB-1000-50108ABC"</getetag>
        <current-user-principal>
          <href>/principals/__uids__/d817aaec-7d24-5b38-bc2f-6369da72cdd9/</href>
        </current-user-principal>
        <calendar-order xmlns="http://apple.com/ns/ical/">1</calendar-order>
        <displayname>calendar</displayname>
        <calendar-color xmlns="http://apple.com/ns/ical/">#F64F00FF</calendar-color>
        <getctag xmlns="http://calendarserver.org/ns/">2012-07-26 00:09:32.361284</getctag>
        <getcontenttype>httpd/unix-directory</getcontenttype>
        <supportedlock>
          <lockentry>
            <lockscope>
              <exclusive />
            </lockscope>
            <locktype>
              <write />
            </locktype>
          </lockentry>
          <lockentry>
            <lockscope>
              <shared />
            </lockscope>
            <locktype>
              <write />
            </locktype>
          </lockentry>
        </supportedlock>
        <resourcetype>
          <collection />
          <calendar xmlns="urn:ietf:params:xml:ns:caldav" />
        </resourcetype>
        <getcontentlength />
        <schedule-calendar-transp xmlns="urn:ietf:params:xml:ns:caldav">
          <opaque />
        </schedule-calendar-transp>
        <getlastmodified>Thu, 26 Jul 2012 00:09:32 GMT</getlastmodified>
        <creationdate>2012-07-26T00:09:32Z</creationdate>
        <resource-class xmlns="http://twistedmatrix.com/xml_namespace/dav/">CalDAVFile</resource-class>
      </prop>
      <status>HTTP/1.1 200 OK</status>
    </propstat>
  </response>
  <response>
    <href>/calendars/users/test/8C1F393E-04E8-428A-819A-933C3A9338AD/</href>
    <propstat>
      <prop>
        <getetag>"43AA-1000-50079D1C"</getetag>
        <current-user-principal>
          <href>/principals/__uids__/d817aaec-7d24-5b38-bc2f-6369da72cdd9/</href>
        </current-user-principal>
        <calendar-order xmlns="http://apple.com/ns/ical/">0</calendar-order>
        <displayname>Jon Wood Calendar</displayname>
        <calendar-color xmlns="http://apple.com/ns/ical/">#711a76</calendar-color>
        <getctag xmlns="http://calendarserver.org/ns/">2012-07-19 05:37:32.673835</getctag>
        <getcontenttype>httpd/unix-directory</getcontenttype>
        <supportedlock>
          <lockentry>
            <lockscope>
              <exclusive />
            </lockscope>
            <locktype>
              <write />
            </locktype>
          </lockentry>
          <lockentry>
            <lockscope>
              <shared />
            </lockscope>
            <locktype>
              <write />
            </locktype>
          </lockentry>
        </supportedlock>
        <resourcetype>
          <collection />
          <calendar xmlns="urn:ietf:params:xml:ns:caldav" />
        </resourcetype>
        <getcontentlength />
        <schedule-calendar-transp xmlns="urn:ietf:params:xml:ns:caldav">
          <transparent />
        </schedule-calendar-transp>
        <getlastmodified>Thu, 19 Jul 2012 05:37:32 GMT</getlastmodified>
        <creationdate>2012-07-19T05:37:32Z</creationdate>
        <resource-class xmlns="http://twistedmatrix.com/xml_namespace/dav/">CalDAVFile</resource-class>
      </prop>
      <status>HTTP/1.1 200 OK</status>
    </propstat>
  </response>
  <response>
    <href>/calendars/users/test/outbox/</href>
    <propstat>
      <prop>
        <getetag>"D4E-1000-4FFB15AF"</getetag>
        <current-user-principal>
          <href>/principals/__uids__/d817aaec-7d24-5b38-bc2f-6369da72cdd9/</href>
        </current-user-principal>
        <displayname>outbox</displayname>
        <getctag xmlns="http://calendarserver.org/ns/">2012-07-09 17:32:31.950308</getctag>
        <getcontenttype>httpd/unix-directory</getcontenttype>
        <supportedlock>
          <lockentry>
            <lockscope>
              <exclusive />
            </lockscope>
            <locktype>
              <write />
            </locktype>
          </lockentry>
          <lockentry>
            <lockscope>
              <shared />
            </lockscope>
            <locktype>
              <write />
            </locktype>
          </lockentry>
        </supportedlock>
        <resourcetype>
          <collection />
          <schedule-outbox xmlns="urn:ietf:params:xml:ns:caldav" />
        </resourcetype>
        <getcontentlength />
        <getlastmodified>Mon, 09 Jul 2012 17:32:31 GMT</getlastmodified>
        <creationdate>2012-07-09T17:32:31Z</creationdate>
        <resource-class xmlns="http://twistedmatrix.com/xml_namespace/dav/">ScheduleOutboxFile</resource-class>
      </prop>
      <status>HTTP/1.1 200 OK</status>
    </propstat>
  </response>
  <response>
    <href>/calendars/users/test/freebusy</href>
    <propstat>
      <prop>
        <getetag>"D7D-0-4FFC3F7C"</getetag>
        <current-user-principal>
          <href>/principals/__uids__/d817aaec-7d24-5b38-bc2f-6369da72cdd9/</href>
        </current-user-principal>
        <displayname>freebusy</displayname>
        <getcontenttype>text/plain</getcontenttype>
        <supportedlock>
          <lockentry>
            <lockscope>
              <exclusive />
            </lockscope>
            <locktype>
              <write />
            </locktype>
          </lockentry>
          <lockentry>
            <lockscope>
              <shared />
            </lockscope>
            <locktype>
              <write />
            </locktype>
          </lockentry>
        </supportedlock>
        <resourcetype>
          <free-busy-url xmlns="http://calendarserver.org/ns/" />
        </resourcetype>
        <getcontentlength>0</getcontentlength>
        <getlastmodified>Tue, 10 Jul 2012 14:43:08 GMT</getlastmodified>
        <creationdate>2012-07-10T14:43:08Z</creationdate>
        <resource-class xmlns="http://twistedmatrix.com/xml_namespace/dav/">FreeBusyURLFile</resource-class>
      </prop>
      <status>HTTP/1.1 200 OK</status>
    </propstat>
  </response>
  <response>
    <href>/calendars/users/test/inbox/</href>
    <propstat>
      <prop>
        <getetag>"42FB-1000-4FF21C60"</getetag>
        <current-user-principal>
          <href>/principals/__uids__/d817aaec-7d24-5b38-bc2f-6369da72cdd9/</href>
        </current-user-principal>
        <displayname>inbox</displayname>
        <getctag xmlns="http://calendarserver.org/ns/">2012-07-02 22:10:40.527683</getctag>
        <getcontenttype>httpd/unix-directory</getcontenttype>
        <supportedlock>
          <lockentry>
            <lockscope>
              <exclusive />
            </lockscope>
            <locktype>
              <write />
            </locktype>
          </lockentry>
          <lockentry>
            <lockscope>
              <shared />
            </lockscope>
            <locktype>
              <write />
            </locktype>
          </lockentry>
        </supportedlock>
        <resourcetype>
          <collection />
          <schedule-inbox xmlns="urn:ietf:params:xml:ns:caldav" />
        </resourcetype>
        <getcontentlength />
        <schedule-default-calendar-URL xmlns="urn:ietf:params:xml:ns:caldav">
          <href xmlns="DAV:">/calendars/__uids__/d817aaec-7d24-5b38-bc2f-6369da72cdd9/calendar</href>
        </schedule-default-calendar-URL>
        <getlastmodified>Mon, 02 Jul 2012 22:10:40 GMT</getlastmodified>
        <creationdate>2012-07-02T22:10:40Z</creationdate>
        <resource-class xmlns="http://twistedmatrix.com/xml_namespace/dav/">ScheduleInboxFile</resource-class>
      </prop>
      <status>HTTP/1.1 200 OK</status>
    </propstat>
  </response>
</multistatus>

接下来,除了针对不同的网址,我尝试了相同的请求。这次,我使用了通过查询主体获得的URL。现在结果仍然包含初始集合,但它们不包含日历。

PROPFIND /calendars/__uids__/d817aaec-7d24-5b38-bc2f-6369da72cdd9/ (CalendarHomeSet)

<propfind xmlns="DAV:">
  <allprop />
</propfind>

响应:

<multistatus xmlns="DAV:">
  <response>
    <href>/calendars/__uids__/d817aaec-7d24-5b38-bc2f-6369da72cdd9/</href>
    <propstat>
      <prop>
        <getetag>"4293-1000-4FFC9A16"</getetag>
        <current-user-principal>
          <href>/principals/__uids__/d817aaec-7d24-5b38-bc2f-6369da72cdd9/</href>
        </current-user-principal>
        <displayname>Test User</displayname>
        <getcontenttype>httpd/unix-directory</getcontenttype>
        <supportedlock>
          <lockentry>
            <lockscope>
              <exclusive />
            </lockscope>
            <locktype>
              <write />
            </locktype>
          </lockentry>
          <lockentry>
            <lockscope>
              <shared />
            </lockscope>
            <locktype>
              <write />
            </locktype>
          </lockentry>
        </supportedlock>
        <resourcetype>
          <collection />
        </resourcetype>
        <getcontentlength />
        <getlastmodified>Tue, 10 Jul 2012 21:09:42 GMT</getlastmodified>
        <creationdate>2012-07-10T21:09:42Z</creationdate>
        <resource-class xmlns="http://twistedmatrix.com/xml_namespace/dav/">CalendarHomeFile</resource-class>
      </prop>
      <status>HTTP/1.1 200 OK</status>
    </propstat>
  </response>
</multistatus>

第三次编辑:

这是我用来获取日历主页的请求和响应:

REPORT /principals/users/test/

<D:principal-match xmlns:D="DAV:">
  <D:self />
  <D:prop>
    <C:calendar-home-set xmlns:C="urn:ietf:params:xml:ns:caldav" />
  </D:prop>
</D:principal-match>

响应:

<multistatus xmlns="DAV:">
  <response>
    <href>/principals/users/test/</href>
    <propstat>
      <prop>
        <calendar-home-set xmlns="urn:ietf:params:xml:ns:caldav">
          <href xmlns="DAV:">/calendars/__uids__/d817aaec-7d24-5b38-bc2f-6369da72cdd9</href>
        </calendar-home-set>
      </prop>
      <status>HTTP/1.1 200 OK</status>
    </propstat>
  </response>
</multistatus>

1 个答案:

答案 0 :(得分:3)

我现在能想到的两件事:

  1. 您是否指定了深度:1标题?
  2. 新用户是否真的有日历?对于新用户,该列表可能只是空的。
  3. 如果这些指针无效,您应该显示完整的请求和响应。

    修改

    这就是你应该如何在CalDAV中进行发现。

    1. 在用户提供的网址上执行PROPFIND,请求{DAV:}current-user-principal
    2. 使用此网址,您可以执行PROPFIND以查找有关该用户的更多信息。在这里,您通常应该在caldav名称空间中请求calendar-home-set属性。
    3. 然后,使用calendar-home-set,执行PROPFIND(深度:1)查找日历。
    4. 我有一种感觉,因为你做了一个主要匹配,并且不使用current-user-principal;这有点不对劲。但我不完全确定。我的预感很简单,你检测到的日历 - 家庭设置是错误的。