0

我正在尝试在NWebDAV和 ASP.NET Core 3.1 之上实现自定义 CardDAV 服务器,使用现有数据库作为联系人的实际数据源。(NWebDAV 似乎对基本的 WebDAV 概念有很好的支持,比如响应PROPFIND。开箱即用,运行它的示例项目来服务你的主目录似乎工作得很好。OTOH,像这样的东西REPORT显然丢失了,我还不确定如何很多工作要做。)

我使用 iOS 13 作为我的主要测试客户端。

我已经成功地将它:

  • 将我的服务器添加为帐户时通过“验证”(包括基本身份验证)
  • 在“通讯录”应用的“组”视图中显示我正在服务的多个通讯簿

所以我知道它正在解析我的PROPFIND回答。但后来,什么都没有。据我了解,它应该向我的服务器发出某种REPORT请求,要么首先进行完全同步,要么——在搜索字段中输入内容时——查询特定联系人。它似乎永远不会尝试。

我给它类似的东西:

<addressbook-home-set xmlns="urn:ietf:params:xml:ns:carddav">
  <D:href>/addressbooks/sample/108</D:href>
  <D:href>/addressbooks/sample/109</D:href>
</addressbook-home-set>

它会PROPFIND针对每个地址簿发出请求,如下所示:

<?xml version="1.0" encoding="utf-8"?>
<A:propfind xmlns:A="DAV:">
  <A:prop>
    <A:add-member />
    <E:bulk-requests xmlns:E="http://me.com/_namespace/" />
    <A:current-user-privilege-set />
    <A:displayname />
    <E:guardian-restricted xmlns:E="http://me.com/_namespace/" />
    <D:max-image-size xmlns:D="urn:ietf:params:xml:ns:carddav" />
    <D:max-resource-size xmlns:D="urn:ietf:params:xml:ns:carddav" />
    <C:me-card xmlns:C="http://calendarserver.org/ns/" />
    <A:owner />
    <C:push-transports xmlns:C="http://calendarserver.org/ns/" />
    <C:pushkey xmlns:C="http://calendarserver.org/ns/" />
    <A:quota-available-bytes />
    <A:quota-used-bytes />
    <A:resource-id />
    <A:resourcetype />
    <A:supported-report-set />
    <A:sync-token />
  </A:prop>
</A:propfind>

我对此作出如下回应:

<?xml version="1.0" encoding="utf-8"?>
<D:multistatus xmlns:D="DAV:" xmlns:Z="urn:schemas-microsoft-com:">
  <D:response>
    <D:href>http://localhost:55946/addressbooks/sample/108</D:href>
    <D:propstat>
      <D:prop>
        <D:add-member />
      </D:prop>
      <D:status>HTTP/1.1 404 Not Found</D:status>
      <D:responsedescription>Property {DAV:}add-member is not supported.</D:responsedescription>
    </D:propstat>
    <D:propstat>
      <D:prop>
        <bulk-requests xmlns="http://me.com/_namespace/" />
      </D:prop>
      <D:status>HTTP/1.1 404 Not Found</D:status>
      <D:responsedescription>Property {http://me.com/_namespace/}bulk-requests is not supported.</D:responsedescription>
    </D:propstat>
    <D:propstat>
      <D:prop>
        <guardian-restricted xmlns="http://me.com/_namespace/" />
      </D:prop>
      <D:status>HTTP/1.1 404 Not Found</D:status>
      <D:responsedescription>Property {http://me.com/_namespace/}guardian-restricted is not supported.</D:responsedescription>
    </D:propstat>
    <D:propstat>
      <D:prop>
        <max-image-size xmlns="urn:ietf:params:xml:ns:carddav" />
      </D:prop>
      <D:status>HTTP/1.1 404 Not Found</D:status>
      <D:responsedescription>Property {urn:ietf:params:xml:ns:carddav}max-image-size is not supported.</D:responsedescription>
    </D:propstat>
    <D:propstat>
      <D:prop>
        <max-resource-size xmlns="urn:ietf:params:xml:ns:carddav" />
      </D:prop>
      <D:status>HTTP/1.1 404 Not Found</D:status>
      <D:responsedescription>Property {urn:ietf:params:xml:ns:carddav}max-resource-size is not supported.</D:responsedescription>
    </D:propstat>
    <D:propstat>
      <D:prop>
        <D:owner />
      </D:prop>
      <D:status>HTTP/1.1 404 Not Found</D:status>
      <D:responsedescription>Property {DAV:}owner is not supported.</D:responsedescription>
    </D:propstat>
    <D:propstat>
      <D:prop>
        <push-transports xmlns="http://calendarserver.org/ns/" />
      </D:prop>
      <D:status>HTTP/1.1 404 Not Found</D:status>
      <D:responsedescription>Property {http://calendarserver.org/ns/}push-transports is not supported.</D:responsedescription>
    </D:propstat>
    <D:propstat>
      <D:prop>
        <pushkey xmlns="http://calendarserver.org/ns/" />
      </D:prop>
      <D:status>HTTP/1.1 404 Not Found</D:status>
      <D:responsedescription>Property {http://calendarserver.org/ns/}pushkey is not supported.</D:responsedescription>
    </D:propstat>
    <D:propstat>
      <D:prop>
        <D:quota-available-bytes />
      </D:prop>
      <D:status>HTTP/1.1 404 Not Found</D:status>
      <D:responsedescription>Property {DAV:}quota-available-bytes is not supported.</D:responsedescription>
    </D:propstat>
    <D:propstat>
      <D:prop>
        <D:quota-used-bytes />
      </D:prop>
      <D:status>HTTP/1.1 404 Not Found</D:status>
      <D:responsedescription>Property {DAV:}quota-used-bytes is not supported.</D:responsedescription>
    </D:propstat>
    <D:propstat>
      <D:prop>
        <D:resource-id />
      </D:prop>
      <D:status>HTTP/1.1 404 Not Found</D:status>
      <D:responsedescription>Property {DAV:}resource-id is not supported.</D:responsedescription>
    </D:propstat>
    <D:propstat>
      <D:prop>
        <D:sync-token />
      </D:prop>
      <D:status>HTTP/1.1 404 Not Found</D:status>
      <D:responsedescription>Property {DAV:}sync-token is not supported.</D:responsedescription>
    </D:propstat>
    <D:propstat>
      <D:prop>
        <D:current-user-privilege-set>
          <D:privilege>
            <D:read />
          </D:privilege>
          <D:privilege>
            <D:read-acl />
          </D:privilege>
          <D:privilege>
            <D:read-current-user-privilege-set />
          </D:privilege>
          <D:privilege>
            <D:write />
          </D:privilege>
          <D:privilege>
            <D:bind />
          </D:privilege>
        </D:current-user-privilege-set>
        <D:displayname>SampleContacts108</D:displayname>
        <me-card xmlns="http://calendarserver.org/ns/">
          <D:href>/addressbooks/sample/108/contact-49191/</D:href>
        </me-card>
        <D:resourcetype>
          <D:collection />
          <addressbook xmlns="urn:ietf:params:xml:ns:carddav" />
        </D:resourcetype>
        <D:supported-report-set>
          <D:supported-report>
            <addressbook-query xmlns="urn:ietf:params:xml:ns:carddav" />
          </D:supported-report>
          <D:supported-report>
            <addressbook-multiget xmlns="urn:ietf:params:xml:ns:carddav" />
          </D:supported-report>
          <D:supported-report>
            <D:expand-property />
          </D:supported-report>
        </D:supported-report-set>
      </D:prop>
      <D:status>HTTP/1.1 200 OK</D:status>
    </D:propstat>
  </D:response>
  <D:response>
    <D:href>http://localhost:55946/addressbooks/sample/108/Bar,Foo</D:href>
    <D:propstat>
      <D:prop>
        <D:add-member />
      </D:prop>
      <D:status>HTTP/1.1 404 Not Found</D:status>
      <D:responsedescription>Property {DAV:}add-member is not supported.</D:responsedescription>
    </D:propstat>
    <D:propstat>
      <D:prop>
        <bulk-requests xmlns="http://me.com/_namespace/" />
      </D:prop>
      <D:status>HTTP/1.1 404 Not Found</D:status>
      <D:responsedescription>Property {http://me.com/_namespace/}bulk-requests is not supported.</D:responsedescription>
    </D:propstat>
    <D:propstat>
      <D:prop>
        <D:current-user-privilege-set />
      </D:prop>
      <D:status>HTTP/1.1 404 Not Found</D:status>
      <D:responsedescription>Property {DAV:}current-user-privilege-set is not supported.</D:responsedescription>
    </D:propstat>
    <D:propstat>
      <D:prop>
        <guardian-restricted xmlns="http://me.com/_namespace/" />
      </D:prop>
      <D:status>HTTP/1.1 404 Not Found</D:status>
      <D:responsedescription>Property {http://me.com/_namespace/}guardian-restricted is not supported.</D:responsedescription>
    </D:propstat>
    <D:propstat>
      <D:prop>
        <max-image-size xmlns="urn:ietf:params:xml:ns:carddav" />
      </D:prop>
      <D:status>HTTP/1.1 404 Not Found</D:status>
      <D:responsedescription>Property {urn:ietf:params:xml:ns:carddav}max-image-size is not supported.</D:responsedescription>
    </D:propstat>
    <D:propstat>
      <D:prop>
        <max-resource-size xmlns="urn:ietf:params:xml:ns:carddav" />
      </D:prop>
      <D:status>HTTP/1.1 404 Not Found</D:status>
      <D:responsedescription>Property {urn:ietf:params:xml:ns:carddav}max-resource-size is not supported.</D:responsedescription>
    </D:propstat>
    <D:propstat>
      <D:prop>
        <me-card xmlns="http://calendarserver.org/ns/" />
      </D:prop>
      <D:status>HTTP/1.1 404 Not Found</D:status>
      <D:responsedescription>Property {http://calendarserver.org/ns/}me-card is not supported.</D:responsedescription>
    </D:propstat>
    <D:propstat>
      <D:prop>
        <D:owner />
      </D:prop>
      <D:status>HTTP/1.1 404 Not Found</D:status>
      <D:responsedescription>Property {DAV:}owner is not supported.</D:responsedescription>
    </D:propstat>
    <D:propstat>
      <D:prop>
        <push-transports xmlns="http://calendarserver.org/ns/" />
      </D:prop>
      <D:status>HTTP/1.1 404 Not Found</D:status>
      <D:responsedescription>Property {http://calendarserver.org/ns/}push-transports is not supported.</D:responsedescription>
    </D:propstat>
    <D:propstat>
      <D:prop>
        <pushkey xmlns="http://calendarserver.org/ns/" />
      </D:prop>
      <D:status>HTTP/1.1 404 Not Found</D:status>
      <D:responsedescription>Property {http://calendarserver.org/ns/}pushkey is not supported.</D:responsedescription>
    </D:propstat>
    <D:propstat>
      <D:prop>
        <D:quota-available-bytes />
      </D:prop>
      <D:status>HTTP/1.1 404 Not Found</D:status>
      <D:responsedescription>Property {DAV:}quota-available-bytes is not supported.</D:responsedescription>
    </D:propstat>
    <D:propstat>
      <D:prop>
        <D:quota-used-bytes />
      </D:prop>
      <D:status>HTTP/1.1 404 Not Found</D:status>
      <D:responsedescription>Property {DAV:}quota-used-bytes is not supported.</D:responsedescription>
    </D:propstat>
    <D:propstat>
      <D:prop>
        <D:resource-id />
      </D:prop>
      <D:status>HTTP/1.1 404 Not Found</D:status>
      <D:responsedescription>Property {DAV:}resource-id is not supported.</D:responsedescription>
    </D:propstat>
    <D:propstat>
      <D:prop>
        <D:resourcetype />
      </D:prop>
      <D:status>HTTP/1.1 404 Not Found</D:status>
      <D:responsedescription>Property {DAV:}resourcetype is not supported.</D:responsedescription>
    </D:propstat>
    <D:propstat>
      <D:prop>
        <D:supported-report-set />
      </D:prop>
      <D:status>HTTP/1.1 404 Not Found</D:status>
      <D:responsedescription>Property {DAV:}supported-report-set is not supported.</D:responsedescription>
    </D:propstat>
    <D:propstat>
      <D:prop>
        <D:sync-token />
      </D:prop>
      <D:status>HTTP/1.1 404 Not Found</D:status>
      <D:responsedescription>Property {DAV:}sync-token is not supported.</D:responsedescription>
    </D:propstat>
    <D:propstat>
      <D:prop>
        <D:displayname>Bar, Foo</D:displayname>
      </D:prop>
      <D:status>HTTP/1.1 200 OK</D:status>
    </D:propstat>
  </D:response>
</D:multistatus>

(我已经实现me-card了,因为有人说不这样做可能会使 iOS 联系人崩溃,并希望它会提示 iOS至少尝试获取我的卡片。但是,唉。)

此响应包括地址簿本身的元数据以及其中的示例联系人。我不确定这是否正确,但离开那个联系似乎并没有改变任何事情。

我支持报告addessbook-queryaddressbook-multiget. 我对规范中的8. Address Book Reports的阅读是,这应该足以符合标准。

让我感到困惑的是,只有……什么都没有。没有面向用户的错误,没有进一步的请求等。

我确实在控制台中找到了一些东西:

com.apple.dataaccess    debug   10:52:13.523530+0200    dataaccessd <private>: There are no server side items to grab, so I'm outta here

但我不知道这是否指的是这个帐户(可能是不同的服务器)。如果是这样,我很想知道是什么让 iOS 得出了这个结论?

所以,我的主要问题是:我是否有基本假设正确,即 CardDAV 客户端最终应该发出REPORT查询联系人的请求?

4

0 回答 0