Created
December 27, 2011 04:49
-
-
Save mythz/1522749 to your computer and use it in GitHub Desktop.
ServiceStack RestFiles vs WCF Web APIs port
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
/* | |
Contains the file manager implementation of ServiceStack's REST /files Web Service: | |
Demo: http://www.servicestack.net/RestFiles/ | |
GitHub: https://github.com/ServiceStack/ServiceStack.Examples/ | |
*/ | |
using System; | |
using System.IO; | |
using System.Net; | |
using RestFiles.ServiceInterface.Support; | |
using RestFiles.ServiceModel; | |
using RestFiles.ServiceModel.Types; | |
using ServiceStack.Common.Web; | |
using ServiceStack.ServiceHost; | |
using ServiceStack.ServiceInterface; | |
using File = System.IO.File; | |
namespace RestFiles.ServiceInterface | |
{ | |
public class FilesService : Service | |
{ | |
public AppConfig Config { get; set; } | |
public object Get(Files request) | |
{ | |
var targetFile = GetAndValidateExistingPath(request); | |
var isDirectory = Directory.Exists(targetFile.FullName); | |
if (!isDirectory && request.ForDownload) | |
return new HttpResult(targetFile, asAttachment: true); | |
var response = isDirectory | |
? new FilesResponse { Directory = GetFolderResult(targetFile.FullName) } | |
: new FilesResponse { File = GetFileResult(targetFile) }; | |
return response; | |
} | |
public void Post(Files request) | |
{ | |
var targetDir = GetPath(request); | |
var isExistingFile = targetDir.Exists | |
&& (targetDir.Attributes & FileAttributes.Directory) != FileAttributes.Directory; | |
if (isExistingFile) | |
throw new NotSupportedException( | |
"POST only supports uploading new files. Use PUT to replace contents of an existing file"); | |
if (!Directory.Exists(targetDir.FullName)) | |
Directory.CreateDirectory(targetDir.FullName); | |
foreach (var uploadedFile in base.RequestContext.Files) | |
{ | |
var newFilePath = Path.Combine(targetDir.FullName, uploadedFile.FileName); | |
uploadedFile.SaveTo(newFilePath); | |
} | |
} | |
public void Put(Files request) | |
{ | |
var targetFile = GetAndValidateExistingPath(request); | |
if (!this.Config.TextFileExtensions.Contains(targetFile.Extension)) | |
throw new NotSupportedException("PUT Can only update text files, not: " + targetFile.Extension); | |
if (request.TextContents == null) | |
throw new ArgumentNullException("TextContents"); | |
File.WriteAllText(targetFile.FullName, request.TextContents); | |
} | |
public void Delete(Files request) | |
{ | |
var targetFile = GetAndValidateExistingPath(request); | |
File.Delete(targetFile.FullName); | |
} | |
private FolderResult GetFolderResult(string targetPath) | |
{ | |
var result = new FolderResult(); | |
foreach (var dirPath in Directory.GetDirectories(targetPath)) | |
{ | |
var dirInfo = new DirectoryInfo(dirPath); | |
if (this.Config.ExcludeDirectories.Contains(dirInfo.Name)) continue; | |
result.Folders.Add(new Folder | |
{ | |
Name = dirInfo.Name, | |
ModifiedDate = dirInfo.LastWriteTimeUtc, | |
FileCount = dirInfo.GetFiles().Length | |
}); | |
} | |
foreach (var filePath in Directory.GetFiles(targetPath)) | |
{ | |
var fileInfo = new FileInfo(filePath); | |
result.Files.Add(new ServiceModel.Types.File | |
{ | |
Name = fileInfo.Name, | |
Extension = fileInfo.Extension, | |
FileSizeBytes = fileInfo.Length, | |
ModifiedDate = fileInfo.LastWriteTimeUtc, | |
IsTextFile = Config.TextFileExtensions.Contains(fileInfo.Extension), | |
}); | |
} | |
return result; | |
} | |
private FileInfo GetPath(Files request) | |
{ | |
return new FileInfo(Path.Combine(this.Config.RootDirectory, request.Path.GetSafePath())); | |
} | |
private FileInfo GetAndValidateExistingPath(Files request) | |
{ | |
var targetFile = GetPath(request); | |
if (!targetFile.Exists && !Directory.Exists(targetFile.FullName)) | |
throw new HttpError(HttpStatusCode.NotFound, new FileNotFoundException("Could not find: " + request.Path)); | |
return targetFile; | |
} | |
private FileResult GetFileResult(FileInfo fileInfo) | |
{ | |
var isTextFile = this.Config.TextFileExtensions.Contains(fileInfo.Extension); | |
return new FileResult | |
{ | |
Name = fileInfo.Name, | |
Extension = fileInfo.Extension, | |
FileSizeBytes = fileInfo.Length, | |
IsTextFile = isTextFile, | |
Contents = isTextFile ? File.ReadAllText(fileInfo.FullName) : null, | |
ModifiedDate = fileInfo.LastWriteTimeUtc, | |
}; | |
} | |
} | |
} |
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
/* | |
Contains the file manager implementation of WCF Web APIs REST /files Web Service: | |
Demo: http://webapi.alexonasp.net/restfiles/ | |
GitHub: https://github.com/AlexZeitler/WebApi.Examples/ | |
*/ | |
using System; | |
using System.Collections.Generic; | |
using System.IO; | |
using System.Json; | |
using System.Linq; | |
using System.Net; | |
using System.Net.Http; | |
using System.Net.Http.Headers; | |
using System.ServiceModel.Web; | |
using System.Web; | |
using WebApi.RestFiles.Types; | |
using File = WebApi.RestFiles.Types.File; | |
namespace WebApi.RestFiles.Operations | |
{ | |
public class FilesApi | |
{ | |
readonly AppConfig _config; | |
public FilesApi(AppConfig config) { | |
_config = config; | |
} | |
public AppConfig Config { | |
get { return _config; } | |
} | |
[WebGet(UriTemplate = "{*Path}")] | |
public HttpResponseMessage Get(string path, HttpRequestMessage request) | |
{ | |
var targetPath = Path.Combine(Config.RootDirectory, path.Replace("/","\\")); | |
var forDownload = false; | |
var queryString = HttpUtility.ParseQueryString(request.RequestUri.Query.ToLower()); | |
if(queryString.AllKeys.Contains("fordownload")) { | |
forDownload = bool.Parse(queryString["fordownload"]); | |
} | |
var isDirectory = Directory.Exists(targetPath); | |
if (!isDirectory && forDownload) { | |
var file = new FileStream(targetPath, FileMode.Open); | |
var message = new HttpResponseMessage { | |
Content = new StreamContent(file), | |
}; | |
message.Content.Headers.ContentDisposition = | |
new ContentDispositionHeaderValue("attachment"); | |
return message; | |
} | |
var response = isDirectory | |
? new FilesResponse { Directory = GetFolderResult(targetPath) } | |
: new FilesResponse { File = GetFileResult(new FileInfo(targetPath)) }; | |
return new HttpResponseMessage<FilesResponse>(response); | |
} | |
[WebInvoke(Method = "POST", UriTemplate = "{*Path}")] | |
public HttpResponseMessage Post(string path, HttpRequestMessage request) { | |
var targetPath = Path.Combine(Config.RootDirectory, path.Replace("/", "\\")); | |
var targetDir = new FileInfo(targetPath); | |
var isExistingFile = targetDir.Exists | |
&& (targetDir.Attributes & FileAttributes.Directory) != FileAttributes.Directory; | |
if (isExistingFile) | |
throw new NotSupportedException( | |
"POST only supports uploading new files. Use PUT to replace contents of an existing file"); | |
if (!Directory.Exists(targetDir.FullName)) { | |
Directory.CreateDirectory(targetDir.FullName); | |
return new HttpResponseMessage(HttpStatusCode.OK); | |
} | |
if (request.Content.IsMimeMultipartContent()) { | |
MultipartFormDataStreamProvider streamProvider = new MultipartFormDataStreamProvider(); | |
var task = request.Content.ReadAsMultipartAsync(streamProvider); | |
task.Wait(); | |
IEnumerable<HttpContent> bodyparts = task.Result; | |
IDictionary<string, string> bodyPartFileNames = streamProvider.BodyPartFileNames; | |
foreach (var kv in bodyPartFileNames) { | |
var targetFilePath = Path.Combine(targetPath, Path.GetFileName(kv.Value)); | |
System.IO.File.Copy(kv.Value, targetFilePath); | |
System.IO.File.Delete(kv.Value); | |
} | |
return new HttpResponseMessage(HttpStatusCode.OK); | |
} | |
return new HttpResponseMessage(HttpStatusCode.BadRequest); | |
} | |
[WebInvoke(Method = "DELETE", UriTemplate = "{*Path}")] | |
public HttpResponseMessage Delete(string path) | |
{ | |
var targetPath = Path.Combine(Config.RootDirectory, path.Replace("/", "\\")); | |
System.IO.File.Delete(targetPath); | |
return new HttpResponseMessage(HttpStatusCode.OK); | |
} | |
[WebInvoke(Method = "PUT", UriTemplate = "{*Path}")] | |
public HttpResponseMessage Put(string path, HttpRequestMessage request) | |
{ | |
var targetPath = Path.Combine(Config.RootDirectory, path.Replace("/", "\\")); | |
dynamic formContent = request.Content.ReadAsAsync<JsonValue>().Result; | |
var textContents = (string)formContent.TextContents; | |
if (!this.Config.TextFileExtensions.Contains(Path.GetExtension(targetPath))) | |
throw new NotSupportedException("PUT Can only update text files, not: " + Path.GetExtension(targetPath)); | |
if (textContents == null) | |
throw new ArgumentNullException("TextContents"); | |
System.IO.File.WriteAllText(targetPath, textContents); | |
return new HttpResponseMessage(HttpStatusCode.OK); | |
} | |
private FolderResult GetFolderResult(string targetPath) { | |
var result = new FolderResult(); | |
foreach (var dirPath in Directory.GetDirectories(targetPath)) { | |
var dirInfo = new DirectoryInfo(dirPath); | |
if (Config.ExcludeDirectories.Contains(dirInfo.Name)) continue; | |
result.Folders.Add(new Folder { | |
Name = dirInfo.Name, | |
ModifiedDate = dirInfo.LastWriteTimeUtc, | |
FileCount = dirInfo.GetFiles().Length | |
}); | |
} | |
foreach (var filePath in Directory.GetFiles(targetPath)) { | |
var fileInfo = new FileInfo(filePath); | |
result.Files.Add(new File { | |
Name = fileInfo.Name, | |
Extension = fileInfo.Extension, | |
FileSizeBytes = fileInfo.Length, | |
ModifiedDate = fileInfo.LastWriteTimeUtc, | |
IsTextFile = Config.TextFileExtensions.Contains(fileInfo.Extension), | |
}); | |
} | |
return result; | |
} | |
private FileResult GetFileResult(FileInfo fileInfo) { | |
var isTextFile = this.Config.TextFileExtensions.Contains(fileInfo.Extension); | |
return new FileResult { | |
Name = fileInfo.Name, | |
Extension = fileInfo.Extension, | |
FileSizeBytes = fileInfo.Length, | |
IsTextFile = isTextFile, | |
Contents = isTextFile ? System.IO.File.ReadAllText(fileInfo.FullName) : null, | |
ModifiedDate = fileInfo.LastWriteTimeUtc, | |
}; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment