Created
August 26, 2014 15:52
-
-
Save maxfridbe/7e95101381c3cd95be26 to your computer and use it in GitHub Desktop.
File Upload multipart
This file contains hidden or 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
//API | |
public async Task<HttpResponseMessage> DeployPackage() | |
{ | |
if (!Request.Content.IsMimeMultipartContent("form-data")) | |
{ | |
throw new HttpResponseException(HttpStatusCode.BadRequest); | |
} | |
var provider = await Request.Content.ReadAsMultipartAsync(new InMemoryMultipartFormDataStreamProvider()); | |
//access form data | |
NameValueCollection formData = provider.FormData; | |
var path = formData["path"]; | |
//access files | |
IList<HttpContent> files = provider.Files; | |
//Example: reading a file's stream like below | |
HttpContent file1 = files[0]; | |
Stream file1Stream = await file1.ReadAsStreamAsync(); | |
var loc = Path.Combine(path, cleanupFilename(files[0].Headers.ContentDisposition.FileName)); | |
//var loc = path + "/" + cleanupFilename(files[0].Headers.ContentDisposition.FileName); | |
_klPackInstallerService.DeployPackage(file1Stream, loc); | |
return Success(); | |
} | |
public class InMemoryMultipartFormDataStreamProvider : MultipartStreamProvider | |
{ | |
private NameValueCollection _formData = new NameValueCollection(); | |
private List<HttpContent> _fileContents = new List<HttpContent>(); | |
// Set of indexes of which HttpContents we designate as form data | |
private Collection<bool> _isFormData = new Collection<bool>(); | |
/// <summary> | |
/// Gets a <see cref="NameValueCollection"/> of form data passed as part of the multipart form data. | |
/// </summary> | |
public NameValueCollection FormData | |
{ | |
get { return _formData; } | |
} | |
/// <summary> | |
/// Gets list of <see cref="HttpContent"/>s which contain uploaded files as in-memory representation. | |
/// </summary> | |
public List<HttpContent> Files | |
{ | |
get { return _fileContents; } | |
} | |
public override Stream GetStream(HttpContent parent, HttpContentHeaders headers) | |
{ | |
// For form data, Content-Disposition header is a requirement | |
ContentDispositionHeaderValue contentDisposition = headers.ContentDisposition; | |
if (contentDisposition != null) | |
{ | |
// We will post process this as form data | |
_isFormData.Add(String.IsNullOrEmpty(contentDisposition.FileName)); | |
return new MemoryStream(); | |
} | |
// If no Content-Disposition header was present. | |
throw new InvalidOperationException(string.Format("Did not find required '{0}' header field in MIME multipart body part..", "Content-Disposition")); | |
} | |
/// <summary> | |
/// Read the non-file contents as form data. | |
/// </summary> | |
/// <returns></returns> | |
public override async Task ExecutePostProcessingAsync() | |
{ | |
// Find instances of non-file HttpContents and read them asynchronously | |
// to get the string content and then add that as form data | |
for (int index = 0; index < Contents.Count; index++) | |
{ | |
if (_isFormData[index]) | |
{ | |
HttpContent formContent = Contents[index]; | |
// Extract name from Content-Disposition header. We know from earlier that the header is present. | |
ContentDispositionHeaderValue contentDisposition = formContent.Headers.ContentDisposition; | |
string formFieldName = UnquoteToken(contentDisposition.Name) ?? String.Empty; | |
// Read the contents as string data and add to form data | |
string formFieldValue = await formContent.ReadAsStringAsync(); | |
FormData.Add(formFieldName, formFieldValue); | |
} | |
else | |
{ | |
_fileContents.Add(Contents[index]); | |
} | |
} | |
} | |
/// <summary> | |
/// Remove bounding quotes on a token if present | |
/// </summary> | |
/// <param name="token">Token to unquote.</param> | |
/// <returns>Unquoted token.</returns> | |
private static string UnquoteToken(string token) | |
{ | |
if (String.IsNullOrWhiteSpace(token)) | |
{ | |
return token; | |
} | |
if (token.StartsWith("\"", StringComparison.Ordinal) && token.EndsWith("\"", StringComparison.Ordinal) && token.Length > 1) | |
{ | |
return token.Substring(1, token.Length - 2); | |
} | |
return token; | |
} | |
} |
This file contains hidden or 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
//TS | |
DeployPackage(stream: File /*Stream*/, path: string /*String*/): JQueryPromise<void> { | |
var dfd = $.Deferred<void>(); | |
var data = new FormData(); | |
data.append('SelectedFile', stream); | |
data.append('path', path); | |
var request = new XMLHttpRequest(); | |
request.onreadystatechange = () => { | |
var resp; | |
if (request.readyState == 4) { | |
try { | |
resp = JSON.parse(request.response); | |
if (resp.Success) { | |
dfd.resolve(); | |
} | |
} catch (e) { | |
resp = { | |
status: 'error', | |
data: 'Unknown error occurred: [' + request.responseText + ']' | |
}; | |
} | |
log.Error("Uploading File Failed", JSON.stringify(resp)); | |
dfd.reject(resp); | |
} | |
}; | |
request.upload.addEventListener('progress', e => { | |
//Math.ceil(e.loaded / e.total) * 100 + '%'; | |
}, false); | |
request.open('POST', '/api/AgentService/DeployPackage'); | |
request.send(data); | |
return dfd.promise(); | |
} |
This file contains hidden or 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
<!--Knockout--> | |
<input data-bind="event: { change: function() { UploadPackage($element.files[0]) } }" type="file" /> | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment