2011-09-08 4 views
4

Web MVC3アプリケーション内にあるSphoirum webdavサーバーを使用して構築されたカスタムWebDAVサーバーがあります。これは.Net 4.0プロジェクトです。WebDAVサーバーに保存した後、Word 2010でエラーが報告される

ドキュメントリポジトリはSharePointであり、MVCアプリケーションはフロントエンドであり、WebDAV経由ですべて公開されます。私たちは、IIS 7.5でWebDAV公開を有効にしていないことに注意してください。私は、次のHTTP動詞を実装しました

  • ゲット
  • ヘッド
  • ロック
  • オプション
  • のPropFind

  • を入れて
  • ロック解除

ここで、ワードドキュメントを開くと、最初は読み取り専用モードです。ロックを取得して編集モードにするのは成功ですが、文書に変更を保存するときは、次のようになります。

変更は保存されましたが、エラーのためアップロードできませんでした。

トリックは、その文書がリポジトリに正しく保存され確かであり、そして言葉に私たちのWebDAVサーバーからの応答は、HTTP/200ですが、言葉はそれにもかかわらず文句を言います。 私はまた、Wordで直接SharePointリポジトリから編集しようとしましたが、私のオフィスがどうにか壊れていないことを確認するだけです。 Wordから文書を保存するときにここで

は、PUT要求からの応答です:

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:[email protected] 
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:[email protected] 
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

ところで、これを引き起こしていたSphorium webdavのバグが見つかりました。バグは、メソッドDavLockBase_InternalProcessDavRequest()にあったし、コードの間違った行は:

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

であるべきである。その変更後

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

、ワード2010でファイルを保存うまく働きました。

0

観測:ロックトークンは無効な構文を使用します(Sharepointも同様です)。また、これらのヘッダーの大部分は必要とされるべきではありません(プロプライエタリな)か、PUT応答(Lock-Tokenなど)には適用されません。

最初にmod_davでApacheに公開し、HTTP交換を観察することをお勧めします。

+0

ロックトークンはRFC2518の仕様に準拠していないと私は理解しています。手紙に、私はサーバーとOfficeとSharePointで動作しようとしています。だからもしそれらが間違っていれば、私もあまりにもあります:) – Vanja

+0

(a)RFC 4918を今日見てみる必要があります。 (b)数年前に一般的なWebDAVサーバーを使用していたオフィス。多分彼らはそれを壊したが、それはSharepointをエミュレートしようとする道を行く前に試してみる価値がある。 –

+0

良い点。私はそれを見てみましょう。問題はSphoriumが2518を実装していることですが、私はソースコードを持っているので、拡張機能を追加することが可能です。 – Vanja

1

もしも誰かがこれをやり直すのであれば、上記の答えに基づいて作られた修正と、2010年の単語から作業して見つかったものに修正が加えられます。 "DavLockBase_InternalProcessDavRequest" (私はそれぞれの "訂正"についていくつかのコメントを追加しました)。

メモ(一部の情報hereが見つかりました):2010の単語のwebdav実装の動作は、クライアント側にパッチがインストールされているかどうかによって異なります。したがって、すべての場合に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; 
    } 
関連する問題