@IT会議室は、ITエンジニアに特化した質問・回答コミュニティ「QA@IT」に生まれ変わりました。ぜひご利用ください。
- PR -

[ASP + C# + Exchange] WebDAV で日付の範囲検索ができない

1
投稿者投稿内容
KYO
会議室デビュー日: 2005/10/31
投稿数: 19
投稿日時: 2005-10-31 18:16
いつもお世話になっております。
初投稿です。宜しくお願いいたします。

【環境】
[Exchange]Windows Server 2003 + Exchange Server 2003 Enterprise Edition
[IIS] Windows Server 2003 + IIS 6.0 + ASP.NET 1.1
[Client] Windows XP Professional + Visual Studio 2003

【質問】
WebDAV を使用して、Exchange 上のパブリックフォルダの予定表アイテムの検索を行おうとしています。
下記のサンプルで日付を範囲指定すると、"<" で比較したときのみ「(400) 要求が不適切です。」とエラーが返って来ます。">" や "=" で比較すると問題ありません。

・下記のサンプルの AND 行を除くと検索可能です ( ">" 比較はOK)
・WHERE のみで "<" 比較しても NG です。(AND 句がいけないわけでない)
・dtend を dtstart に変更しても変わりません。(dtend フィールドが間違っているわけではない)
・CAST せずに日付 "2005/10/31" を指定しても同様の結果。

何が原因か、または、どのあたりを確認すればよいかアドバイスいただければ幸いです。
宜しくお願いいたします。

【サンプルコード】
==== WebDAV Query====
SELECT *
FROM scope('Shallow Traversal of "http://exch2003/public/会議室/R3301/"')
WHERE ("urn:schemas:calendar:dtstart" >= CAST("2005-10-25T16:00:00Z" as 'dateTime'))
AND ("urn:schemas:calendar:dtend" <= CAST("2005-10-30T01:00:00Z" as 'dateTime'))
============================


==== C# ====================
/// <summary>
/// WevDAV で検索し、検索結果を戻す
/// </summary>
/// <param name="strRootUri">検索URI</param>
/// <param name="query">WebDAV SELECT Query</param>
/// <returns>検索結果XML</returns>
private string WebDavQuery(string strRootUri, string query)
{

  // Variables.
  HttpWebRequest Request;
  WebResponse Response;
  string strQuery ="";
  byte[] bytes = null;
  Stream RequestStream = null;
  Stream ResponseStream = null;
  DropDownList tmpDDL = new DropDownList();
  
  strQuery = "<?xml version=\\\\"1.0\\\\"?><D:searchrequest xmlns:D = \\\\"DAV:\\\\" >";
  strQuery += "<D:sql> ";
  strQuery += query;
  strQuery += "</D:sql></D:searchrequest>";
  
  // Create the HttpWebRequest object.
  Request = (HttpWebRequest)HttpWebRequest.Create(strRootUri);

  // Add the network credentials to the request.
  Request.Credentials = CredentialCache.DefaultCredentials;;

  // Specify the method.
  Request.Method = "SEARCH";

  // Encode the body using UTF-8.
  bytes = Encoding.UTF8.GetBytes((string)strQuery);

  // Set the content header length. This must be
  // done before writing data to the request stream.
  Request.ContentLength = bytes.Length;

  // Get a reference to the request stream.
  RequestStream = Request.GetRequestStream();

  // Write the SQL query to the request stream.
  RequestStream.Write(bytes, 0, bytes.Length);

  // Close the Stream object to release the connection
  // for further use.
  RequestStream.Close();

  // Set the content type header.
  Request.ContentType = "text/xml";

  // Send the SEARCH method request and get the
  // response from the server.
  Response = (HttpWebResponse)Request.GetResponse();

  // Get the XML response stream.
  ResponseStream = Response.GetResponseStream();

  // Get Stream Data
  StreamReader sr = new StreamReader(ResponseStream);
  string ret = HttpUtility.UrlDecode(HttpUtility.HtmlDecode(sr.ReadToEnd()));

  // Clean up.
  ResponseStream.Close();
  Response.Close();

  return ret;
}
============================
MMX
ぬし
会議室デビュー日: 2001/10/26
投稿数: 861
投稿日時: 2005-10-31 23:08
strQuery
を文字列で取り出し、xmlとして検証すると、わかるのでは
セイン
常連さん
会議室デビュー日: 2005/06/15
投稿数: 24
投稿日時: 2005-11-01 09:21
">"がエラーにならないのであれば、検索対象の位置そのものを入れ替えては?

現状
検索対象>検索日時
検索対象<検索日時

変更
検索対象>検索日時
検索日時>検索対象

逃げの作戦になってしまうかな?


KYO
会議室デビュー日: 2005/10/31
投稿数: 19
投稿日時: 2005-11-01 10:47
コメントありがとうございます。

"<" や ">" が開始タグや終了タグになっているようですね・・・

まず、値の記述を入れ替えて > でのみ比較しましたが NG のようです。

  AND ( CAST("2005-10-30T01:00:00Z" as 'dateTime') >= "urn:schemas:calendar:dtend")

ちゃんと調べていませんが、ダブルクォーテーションやシングルクォーテーションの位置にも関係あるのかもしれません。
('Shallow Traversal of "http://exch2003/public/会議室/R3301/"' を削除すると、IE で XML が表示できたりするので。)


次に SQL 文を CDATA でくくりましたが NG のようです。
<D:searchrequest xmlns:D = "DAV:" ><D:sql><![CDATA[
 SELECT *
 FROM  scope('Shallow Traversal of "http://exch2003/public/会議室/R3301/"')
 WHERE ("urn:schemas:calendar:dtstart" >= CAST("2005-10-25T16:00:00Z" as 'dateTime'))
 AND ("urn:schemas:calendar:dtend" <= CAST("2005-10-30T01:00:00Z" as 'dateTime'))
]]></D:sql></D:searchrequest>


仕方ないので、"<" を "&lt;"、">" を "&gt;" で直接記述すると、とりあえず通りました。

ということで、次のように SQL Query 部分を HtmlEncode することで通るようになりました。
変更前 : strQuery += query;
変更後 : strQuery += HttpUtility.HtmlEncode(query);

検索結果が正しいかはこれから検証しようと思いますが、、、


どうもありがとうございました。



[ メッセージ編集済み 編集者: KYO 編集日時 2005-11-01 10:50 ]
KYO
会議室デビュー日: 2005/10/31
投稿数: 19
投稿日時: 2005-11-01 15:30
テストした結果 HtmlEncode で問題なさそうです。念のため。
1

スキルアップ/キャリアアップ(JOB@IT)