Word 2010 сообщает об ошибке после сохранения на сервере WebDAV - PullRequest
4 голосов
/ 08 сентября 2011

У меня есть пользовательский сервер WebDAV, построенный с использованием Sphoirum сервера webdav, который находится внутри приложения ASP.NET MVC3. Это проект .Net 4.0.

Хранилище документов - это SharePoint, где наше MVC-приложение является для него внешним интерфейсом и предоставляет все это через WebDAV. Просто отметим, что в нашем IIS 7.5 не включена публикация WebDAV.

Я реализовал следующие HTTP-глаголы:

  • Получить
  • Head
  • Блокировка
  • Опция
  • PROPFIND
  • Помещенный
  • Разблокировка

Теперь, когда я открываю документ Word, он сначала находится в режиме только для чтения. Получение блокировки и переход в режим редактирования успешны, но когда я хочу сохранить изменения в своем документе, я получаю следующее:

Ваши изменения были сохранены, но не могли быть загружены из-за ошибки.

Хитрость в том, что документ действительно правильно сохранен в хранилище, и ответ нашего WebDAV-сервера на слово HTTP / 200, но Word, тем не менее, жалуется. Я также пытался редактировать в Word непосредственно из репозитория SharePoint, просто чтобы убедиться, что мой Office как-то не сломан - все работает.

Вот ответ на запрос PUT при сохранении документа из Word:

HTTP/1.1 200 OK
Date: Tue, 06 Sep 2011 12:25:47 GMT
Server: Microsoft-IIS/6.0
X-Powered-By: ASP.NET
MicrosoftSharePointTeamServices: 12.0.0.6545
Last-Modified: Tue, 06 Sep 2011 12:25:47 GMT
ETag: "{F4A63494-D302-4C9B-9C57-D0CB0937A2B0},9"
ResourceTag: rt:F4A63494-D302-4C9B-9C57-D0CB0937A2B0@00000000009
X-MSDAVEXTLockTimeout: Second-3600
Lock-Token: opaquelocktoken:{F4A63494-D302-4C9B-9C57-D0CB0937A2B0}20110906T122532Z
Expires: Mon, 22 Aug 2011 12:25:47 GMT
Cache-Control: private,max-age=0
Content-Length: 0
Public-Extension: http://schemas.microsoft.com/repl-2
Set-Cookie: WSS_KeepSessionAuthenticated=40689; path=/

А вот тот же ответ, для того же документа, с нашего сервера WebDAV:

HTTP/1.1 200 OK
Cache-Control: private,max-age=0
Content-Length: 0
Expires: Wed, 24 Aug 2011 08:03:28 GMT
Last-Modified: Wed, 07 Sep 2011 08:03:28 GMT
ETag: "{4a4331a8-7df6-43e6-bd5f-bb80765e83a2},1"
Server: Microsoft-IIS/7.5
MS-Author-Via: DAV
ResourceTag: rt:4a4331a8-7df6-43e6-bd5f-bb80765e83a2@00000000001
Lock-Token: opaquelocktoken:{4a4331a8-7df6-43e6-bd5f-bb80765e83a2}20110907T080328Z
X-MSDAVEXTLockTimeout: Second-3600
Public-Extension: http://schemas.microsoft.com/repl-2
MicrosoftSharePointTeamServices: 12.0.0.6545
Set-Cookie: WSS_KeepSessionAuthenticated=40689; path=/
X-Powered-By: ASP.NET
Date: Wed, 07 Sep 2011 08:03:27 GMT

Итак, я попытался имитировать некоторые заголовки, которые излучает SharePoint, например MicrosoftSharePointTeamServices , но безрезультатно.

Ответы [ 3 ]

3 голосов
/ 17 сентября 2012

Кстати, я нашел ошибку в Sphorium webdav, которая вызывала это.Ошибка была в методе DavLockBase_InternalProcessDavRequest () , и неправильная строка кода была:

string[] _lockTokens = this.RequestLock.GetLockTokens();

, которая должна быть:

string[] _lockTokens = this.ResponseLock.GetLockTokens();

После этого изменения, сохраняяфайлы в Word 2010 работали нормально.

1 голос
/ 09 сентября 2014

Если кто-то когда-нибудь столкнется с этим снова, вот исправление, которое было построено на основе приведенного выше ответа и того, что я нашел при работе со словом 2010. В основном исправление включает замену кода для метода "DavLockBase_InternalProcessDavRequest" (Я добавил несколько комментариев для каждого «исправления»).

В качестве примечания (нашел некоторую информацию здесь ): поведение реализации webdav для Word 2010 отличается от того, существует липатч установлен на стороне клиента или нет;поэтому 3-я коррекция может понадобиться не во всех случаях!

Надеюсь, это поможет!

private int DavLockBase_InternalProcessDavRequest(object sender, EventArgs e)
    {
        int _responseCode = (int)DavLockResponseCode.Ok;

        //string[] _lockTokens = this.RequestLock.GetLockTokens();
        //#1 the above line is incorrect. replaced with the following:
        string[] _lockTokens = this.ResponseLock.GetLockTokens();

        //Check to see if a lock refresh was requested
        if (base.HttpApplication.Request.Headers["If"] != null)
        {
            if (_lockTokens.Length == 1)
            {
                //#2 not sure why this should be done (or not), however I've seen this in other people corrections.
                //DavRefreshEventArgs _refreshEventArgs = new DavRefreshEventArgs(_lockTokens[0], this.RequestLock.LockTimeout);
                //OnRefreshLockDavRequest(_refreshEventArgs);
            }

            base.HttpApplication.Response.AppendHeader("Timeout", "Second-" + this.ResponseLock.LockTimeout);
        }
        else
        {
            //New lock request
            StringBuilder _opaquelockTokens = new StringBuilder();
            //#3 finally, added the check below, as most of the times, when using word 2010 there are no lock requests
            if (_lockTokens.Length > 0)
            {
                foreach (string _lockToken in _lockTokens)
                    _opaquelockTokens.Append("<opaquelocktoken:" + _lockToken + ">");

                base.HttpApplication.Response.AppendHeader("Lock-Token", _opaquelockTokens.ToString());
            }
        }

        //Check to see if there were any process errors...
        Enum[] _errorResources = this.ProcessErrorResources;
        if (_errorResources.Length > 0)
        {
            //Append a response node
            XmlDocument _xmlDocument = new XmlDocument();
            XmlNode _responseNode = _xmlDocument.CreateNode(XmlNodeType.Element, _xmlDocument.GetPrefixOfNamespace("DAV:"), "response", "DAV:");

            //Add the HREF
            XmlElement _requestLockHrefElement = _xmlDocument.CreateElement("href", "DAV:");
            _requestLockHrefElement.InnerText = base.RelativeRequestPath;
            _responseNode.AppendChild(_requestLockHrefElement);


            //Add the propstat
            XmlElement _propstatElement = _xmlDocument.CreateElement("propstat", "DAV:");
            XmlElement _propElement = _xmlDocument.CreateElement("prop", "DAV:");
            XmlElement _lockDiscoveryElement = _xmlDocument.CreateElement("lockdiscovery", "DAV:");
            _propElement.AppendChild(_lockDiscoveryElement);
            _propstatElement.AppendChild(_propElement);

            XmlElement _statusElement = _xmlDocument.CreateElement("status", "DAV:");
            _statusElement.InnerText = InternalFunctions.GetEnumHttpResponse(DavLockResponseCode.FailedDependency);
            _propstatElement.AppendChild(_statusElement);

            _responseNode.AppendChild(_propstatElement);

            base.SetResponseXml(InternalFunctions.ProcessErrorRequest(this.ProcessErrors, _responseNode));
            _responseCode = (int)ServerResponseCode.MultiStatus;
        }
        else
        {
            //No issues
            using (Stream _responseStream = new MemoryStream())
            {
                XmlTextWriter _xmlWriter = new XmlTextWriter(_responseStream, new UTF8Encoding(false));

                _xmlWriter.Formatting = Formatting.Indented;
                _xmlWriter.IndentChar = '\t';
                _xmlWriter.Indentation = 1;
                _xmlWriter.WriteStartDocument();

                //Open the prop element section
                _xmlWriter.WriteStartElement("D", "prop", "DAV:");
                _xmlWriter.WriteStartElement("lockdiscovery", "DAV:");
                this.ResponseLock.ActiveLock.WriteTo(_xmlWriter);
                _xmlWriter.WriteEndElement();
                _xmlWriter.WriteEndElement();

                _xmlWriter.WriteEndDocument();
                _xmlWriter.Flush();

                base.SetResponseXml(_responseStream);
                _xmlWriter.Close();
            }
        }

        return _responseCode;
    }
0 голосов
/ 08 сентября 2011

Замечание: маркер блокировки использует недопустимый синтаксис (как и Sharepoints).Также;большинство из этих заголовков не должны быть необходимыми (проприетарными) или не должны применяться к ответу PUT (например, Lock-Token).

Я бы рекомендовал сначала попробовать опубликовать в Apache с mod_dav и наблюдатьобмен HTTP.

...