【问题标题】:Getting User's List of Calendars from CalDAV从 CalDAV 获取用户的日历列表
【发布时间】:2012-07-24 00:24:11
【问题描述】:

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

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

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

结果是一个带有多个&lt;response&gt; 元素的&lt;multistatus&gt; 元素。如果我提取 resourcetype 是日历的元素,我会得到我的日历列表。

但是,当我们添加其他用户时,这会产生“未找到”错误,因此我改为使用“主要匹配”请求来获取当前用户的“日历-主页-设置”路径。

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

我这辈子都想不出能让我在所有情况下都获得日历用户列表的神奇方法。

编辑:

这是我的一些代码。我最初尝试的“/calendars/users/test/”URL 是从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。这一次,我使用了通过查询主体获得的 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>

【问题讨论】:

    标签: c# webdav caldav


    【解决方案1】:

    我现在能想到的两件事:

    1. 您是否指定了 Depth: 1 标头?
    2. 新用户真的有日历吗?对于新用户,该列表可能只是空的。

    如果这些提示没有帮助,您应该显示完整的请求和响应。

    编辑

    这就是您通常应该在 CalDAV 中进行发现的方式。

    1. 在用户提供的 url 上执行 PROPFIND,请求 {DAV:}current-user-principal
    2. 使用此 URL,您可以执行 PROPFIND 以查找有关用户的更多信息。在这里,您通常应该请求 caldav 命名空间中的 calendar-home-set 属性。
    3. 然后,使用 calendar-home-set,执行 PROPFIND(深度:1)来查找日历。

    我有一种感觉,因为您进行了主体匹配,并且不使用当前用户主体;这有点不对劲。但我不完全确定。我的直觉是你检测到的 calendar-home-set 是错误的。

    【讨论】:

    • 感谢您的回复。我确实使用了 Depth = 1 并且能够确认所有用户都有默认日历。我编辑了我的问题以显示更多我的代码。感谢您的帮助。
    • 我很想看到确切地您发送到服务器的内容,然后返回.. 以 xml 格式。我是 CalDAV 服务器 (SabreDAV) 的作者,所以请求/响应主体对我来说会更有帮助:)
    • 感谢您的回复。我在问题的末尾添加了确切的内容。我期待第二个响应与第一个响应相同。 (另外,如果我们想从 DCS 迁移到 SabreDAV,那是什么样的?需要什么工具吗?
    • 我可以看出它是 DCS。最突出的是基本网址。第一个以 /calendars/users 开头,第二个以 /calendars/__uids__ 开头。这让我想知道您是否正确获得了 calendar-home-set。 calendar-home-set 可以是一个href列表,所以也许你只抓住了第一个?另外..如果您正确实施 CalDAV 协议,切换到 SabreDAV 应该很容易.. 虽然数据迁移更难
    • 到目前为止,您走在正确的道路上,但是是的.. 我要问的最后一件事是.. 您能否显示用于获取 calendar-home-set 的请求和响应。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多