Created
May 11, 2012 01:21
-
-
Save kiyokura/2656920 to your computer and use it in GitHub Desktop.
フォルダ作成とファイルアップロードする為だけの簡易WebDAVクライアントClass
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Net; | |
using System.IO; | |
using System.Diagnostics; | |
namespace TinyWebDav | |
{ | |
/// <summary> | |
/// 簡易WebDAVクライアントクラス | |
/// </summary> | |
public class WebDavClient | |
{ | |
#region "プライベートフィールド" | |
private string userName; | |
private string userPassword; | |
private string baseUrl; | |
#endregion | |
#region"コンストラクタ" | |
/// <summary> | |
/// コンストラクタ | |
/// </summary> | |
/// <param name="userName">ユーザ名</param> | |
/// <param name="userPassword">パスワード</param> | |
/// <param name="baseUrl">ベースURL</param> | |
public WebDavClient(string userName, string userPassword, string baseUrl) | |
{ | |
if (string.IsNullOrEmpty(userName)) | |
{ | |
throw new AggregateException("ユーザ名が空です"); | |
} | |
if (string.IsNullOrEmpty(baseUrl)) | |
{ | |
throw new AggregateException("ベースが空です"); | |
} | |
this.userName = userName; | |
this.userPassword = userPassword; | |
this.baseUrl = baseUrl; | |
} | |
#endregion | |
#region"ファイルアップロード" | |
/// <summary> | |
/// ファイルアップロード | |
/// </summary> | |
/// <param name="folderName">アップロード対象フォルダ</param> | |
/// <param name="localPath">アップロード対象ファイルのローカルパス(フルパス)</param> | |
/// <returns>HTTPレスポンスコード</returns> | |
/// <remarks>アップロード後のファイル名はローカルにあるものと同じになる。同一ファイル名は上書きされる。</remarks> | |
public HttpStatusCode UploadFile(string folderName, string localPath) | |
{ | |
return UploadFile(folderName, localPath, Path.GetFileName(localPath)); | |
} | |
/// <summary> | |
/// ファイルアップロード | |
/// </summary> | |
/// <param name="folderName">アップロード先のフォルダ名(ルートに置く場合は空で)</param> | |
/// <param name="localPath">アップロード対象ファイルのローカルパス(フルパス)</param> | |
/// <param name="uploadedFileName">アップロード後のファイル名</param> | |
/// <returns>HTTPレスポンスコード</returns> | |
/// <remarks>同一ファイル名は上書きされる。</remarks> | |
public HttpStatusCode UploadFile(string folderName, string localPath, string uploadedFileName) | |
{ | |
#region"引数チェック" | |
if (!File.Exists(localPath)) | |
throw new FileNotFoundException(string.Format("指定されたファイル<{0}>が存在しません", localPath)); | |
if (string.IsNullOrEmpty(uploadedFileName)) | |
throw new ArgumentException("アップロード後ファイル名が未指定です"); | |
if (uploadedFileName.IndexOfAny(Path.GetInvalidFileNameChars()) > 0) | |
throw new ArgumentException(string.Format("指定されたファイル名<{0}>に使用不可能な文字が含まれています", uploadedFileName)); | |
#endregion | |
try | |
{ | |
// HttpWebRequestを初期化 | |
var req = httpWebRequestFactory(makeUrl(folderName, uploadedFileName)); | |
req.Method = WebRequestMethods.File.UploadFile; | |
// アップロードするファイルをオープン | |
using (FileStream inSt = new FileStream(localPath, FileMode.Open)) | |
{ | |
//HttpWebRequestにサイズを設定 | |
req.ContentLength = inSt.Length; | |
// ファイルをバッファに読み込み・サーバーへ書き込み | |
using (Stream outSt = req.GetRequestStream()) | |
{ | |
int bufSize = 1024*1024; | |
byte[] buffer = new byte[bufSize]; | |
int bytesReaded = 0; | |
while ((bytesReaded = inSt.Read(buffer, 0, bufSize)) > 0) | |
{ | |
outSt.Write(buffer, 0, bytesReaded); | |
} | |
outSt.Flush(); | |
} | |
} | |
// 結果取得 | |
using (HttpWebResponse res = (HttpWebResponse)req.GetResponse()) | |
{ | |
return res.StatusCode; | |
} | |
} | |
catch (WebException we) | |
{ | |
var errResponse = (HttpWebResponse)we.Response; | |
Debug.WriteLine(errResponse.Headers.ToString()); | |
Debug.WriteLine("Status Code: {0}", errResponse.StatusCode); | |
throw; | |
} | |
} | |
#endregion | |
#region"フォルダ作成" | |
/// <summary> | |
/// フォルダ作成 | |
/// </summary> | |
/// <param name="path">作成したいパス(ルート以下を全て記述)</param> | |
/// <returns> | |
/// </returns> | |
/// <remarks> | |
/// 上位のパスが存在しない場合、例外(409)が発生する。 | |
/// </remarks> | |
public HttpStatusCode CreateFolder(string path) | |
{ | |
#region"引数チェック" | |
if (string.IsNullOrEmpty(path)) | |
throw new ArgumentException("引数pathはNullにはできません"); | |
#endregion | |
try | |
{ | |
var req = httpWebRequestFactory(makeUrl(path)); | |
req.Method = WebRequestMethods.Http.MkCol; | |
using (HttpWebResponse res = (HttpWebResponse)req.GetResponse()) | |
{ | |
return res.StatusCode; | |
} | |
} | |
catch (WebException we) | |
{ | |
var errResponse = (HttpWebResponse)we.Response; | |
Debug.WriteLine(errResponse.Headers.ToString()); | |
Debug.WriteLine("Status Code: {0}", errResponse.StatusCode); | |
throw; | |
} | |
} | |
#endregion | |
#region "存在チェック" | |
/// <summary> | |
/// パスが存在するかチェック | |
/// </summary> | |
/// <param name="folerName"></param> | |
/// <param name="fileName"></param> | |
/// <returns></returns> | |
public bool Exists(string folerName, string fileName) | |
{ | |
var req = httpWebRequestFactory(makeUrl(folerName,fileName)); | |
req.Method = WebRequestMethods.Http.Head; | |
HttpWebResponse res; | |
try | |
{ | |
using (res = (HttpWebResponse)req.GetResponse()) | |
{ | |
switch (res.StatusCode) | |
{ | |
case HttpStatusCode.OK: | |
// このあたりは多分OK。 | |
return true; | |
default: | |
Debug.WriteLine(res.Headers.ToString()); | |
Debug.WriteLine("Status Code: {0}", res.StatusCode); | |
return false; | |
} | |
} | |
} | |
catch (WebException we) | |
{ | |
var errResponse = (HttpWebResponse)we.Response; | |
switch (errResponse.StatusCode) | |
{ | |
case HttpStatusCode.Forbidden: | |
// 403だけど帰ってきてるので、存在はしている(と思われる) | |
return true; | |
case HttpStatusCode.NotFound: | |
// 404なので、これは無い。 | |
return false; | |
default: | |
// 他はとりあえずthrowする。 | |
Debug.WriteLine(errResponse.Headers.ToString()); | |
Debug.WriteLine("Status Code: {0}", errResponse.StatusCode); | |
throw; | |
} | |
} | |
} | |
/// <summary> | |
/// パス(ルート以下)が存在するかチェック | |
/// </summary> | |
/// <param name="path">ルート以下のパス</param> | |
/// <returns></returns> | |
public bool Exists(string path) | |
{ | |
var req = httpWebRequestFactory(makeUrl(path)); | |
req.Method = WebRequestMethods.Http.Head; | |
HttpWebResponse res; | |
try | |
{ | |
using (res = (HttpWebResponse)req.GetResponse()) | |
{ | |
switch (res.StatusCode) | |
{ | |
case HttpStatusCode.OK: | |
// このあたりは多分OK。 | |
return true; | |
default: | |
Debug.WriteLine(res.Headers.ToString()); | |
Debug.WriteLine("Status Code: {0}", res.StatusCode); | |
return false; | |
} | |
} | |
} | |
catch (WebException we) | |
{ | |
var errResponse = (HttpWebResponse)we.Response; | |
switch (errResponse.StatusCode) | |
{ | |
case HttpStatusCode.Forbidden: | |
// 403だけど帰ってきてるので、存在はしている(と思われる) | |
return true; | |
case HttpStatusCode.NotFound: | |
// 404なので、これは無い。 | |
return false; | |
default: | |
// 他はとりあえずthrowする。 | |
Debug.WriteLine(errResponse.Headers.ToString()); | |
Debug.WriteLine("Status Code: {0}", errResponse.StatusCode); | |
throw; | |
} | |
} | |
} | |
#endregion | |
#region"ヘルパ" | |
/// <summary> | |
/// HttpWebRequestファクトリー | |
/// </summary> | |
/// <param name="url"></param> | |
/// <returns></returns> | |
private HttpWebRequest httpWebRequestFactory(string url) | |
{ | |
HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(url); | |
req.Credentials = new NetworkCredential(userName, userPassword); | |
return req; | |
} | |
/// <summary> | |
/// リクエスト用のURL作成 | |
/// </summary> | |
/// <param name="folderName"></param> | |
/// <param name="fileName"></param> | |
/// <returns></returns> | |
private string makeUrl(string folderName , string fileName) | |
{ | |
return this.baseUrl.TrimEnd("/".ToCharArray()) + "/" + folderNameNormalizer(folderName) + fileNameNormalizer(fileName); | |
} | |
/// <summary> | |
/// リクエスト用のURL作成 | |
/// </summary> | |
/// <param name="folderName"></param> | |
/// <returns></returns> | |
private string makeUrl(string path) | |
{ | |
return this.baseUrl.TrimEnd("/".ToCharArray()) + "/" + pathNormalizer(path); | |
} | |
/// <summary> | |
/// フォルダ名URL正規化 | |
/// </summary> | |
/// <param name="folderName"></param> | |
/// <returns> | |
/// 正規化された、URL用のフォルダ名(先頭のスラッシュ無し、末尾にスラッシュあり) | |
/// ただし、空文字列の場合はスラッシュ無。 | |
/// </returns> | |
private string folderNameNormalizer(string folderName) | |
{ | |
if (string.IsNullOrEmpty(folderName)) | |
{ | |
return ""; | |
} | |
else | |
{ | |
return folderName.TrimEnd("/".ToCharArray()).TrimStart("/".ToCharArray()) + "/"; | |
} | |
} | |
/// <summary> | |
/// ファイル名URL正規化 | |
/// </summary> | |
/// <param name="fileName"></param> | |
/// <returns> | |
/// 正規化された、URL用のファイル名(先頭のスラッシュ無し) | |
/// </returns> | |
private string fileNameNormalizer(string fileName) | |
{ | |
return fileName.TrimStart("/".ToCharArray()); | |
} | |
/// <summary> | |
/// パス(ルート以下)の正規化 | |
/// </summary> | |
/// <param name="path">パス(ルート以下)</param> | |
/// <returns> | |
/// 正規化された、URL用のパス名(先頭のスラッシュ無し) | |
/// 末尾にもスラッシュは付与しない(ファイル名のケースを考慮) | |
/// </returns> | |
private string pathNormalizer(string path) | |
{ | |
return path.TrimStart("/".ToCharArray()); | |
} | |
#endregion | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment