Created
December 29, 2015 14:58
-
-
Save cakriwut/fab729cad785047cc8f0 to your computer and use it in GitHub Desktop.
ServiceStack Extensions to POST multiple files along with dto.
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
///<summary> | |
/// ServiceClient Base Extensions | |
/// Author: Riwut Libinuko | |
/// Created Date: 29/12/2015 | |
/// Website : http://blog.libinuko.com | |
/// Copyright(c) 2015 | |
/// Use PostFilesWithRequest<TResponse>(...) , to POST metadata and multiple files attachment in single request | |
///</summary> | |
public static class ServiceClientBaseExtensions | |
{ | |
public static void Write(this Stream stream, string text) | |
{ | |
var bytes = Encoding.UTF8.GetBytes(text); | |
stream.Write(bytes, 0, bytes.Length); | |
} | |
internal static void AddBasicAuth(this WebRequest client, string userName, string password) | |
{ | |
client.Headers[ServiceStack.Common.Web.HttpHeaders.Authorization] | |
= "Basic " + Convert.ToBase64String(Encoding.UTF8.GetBytes(userName + ":" + password)); | |
} | |
internal static TResponse HandleResponse<TResponse>(ServiceClientBase service, WebResponse webResponse) | |
{ | |
if (typeof(TResponse) == typeof(HttpWebResponse) && (webResponse is HttpWebResponse)) | |
{ | |
return (TResponse)Convert.ChangeType(webResponse, typeof(TResponse)); | |
} | |
if (typeof(TResponse) == typeof(Stream)) //Callee Needs to dispose manually | |
{ | |
return (TResponse)(object)webResponse.GetResponseStream(); | |
} | |
using (var responseStream = webResponse.GetResponseStream()) | |
{ | |
if (typeof(TResponse) == typeof(string)) | |
{ | |
using (var reader = new StreamReader(responseStream)) | |
{ | |
return (TResponse)(object)reader.ReadToEnd(); | |
} | |
} | |
if (typeof(TResponse) == typeof(byte[])) | |
{ | |
return (TResponse)(object)responseStream.ReadFully(); | |
} | |
var response = service.DeserializeFromStream<TResponse>(responseStream); | |
return response; | |
} | |
} | |
public static TResponse PostFilesWithRequest<TResponse>(this ServiceClientBase sender, string relativeOrAbsoluteUrl, ICredentials creds, object request, params FileStreamInfo[] files) | |
{ | |
var requestUri = sender.GetUrl(relativeOrAbsoluteUrl); | |
Action<Stream, FileStreamInfo, string, string> writeFileStream = null; | |
writeFileStream = (outputStream, inputFileInfo, boundary, newLine) => | |
{ | |
var currentStreamPosition = inputFileInfo.InputStream.Seek(0,SeekOrigin.Begin); | |
var header = String.Format("{0}{1}Content-Disposition: form-data; name=\"{2}\"; filename=\"{3}\"{1}{1}", boundary, newLine, "upload", inputFileInfo.Filename); | |
outputStream.Write(header); | |
var buffer = new byte[4096]; | |
int byteCount; | |
while ((byteCount = inputFileInfo.InputStream.Read(buffer, 0, 4096)) > 0) | |
{ | |
outputStream.Write(buffer, 0, byteCount); | |
} | |
outputStream.Write(newLine); | |
}; | |
//var p = new MultipartFormDataContent(boundary); | |
//p.Add() | |
Func<WebRequest> createWebRequest = () => | |
{ | |
// PrepareWebRequest | |
var webRequest = (HttpWebRequest)WebRequest.Create(requestUri); | |
try | |
{ | |
webRequest.Accept = sender.Accept; | |
webRequest.Method = HttpMethods.Post; | |
webRequest.Headers.Add(sender.Headers); | |
if (sender.Proxy != null) webRequest.Proxy = sender.Proxy; | |
if (sender.Timeout.HasValue) webRequest.Timeout = (int)sender.Timeout.Value.TotalMilliseconds; | |
if (sender.ReadWriteTimeout.HasValue) webRequest.ReadWriteTimeout = (int)sender.ReadWriteTimeout.Value.TotalMilliseconds; | |
if (creds != null) webRequest.Credentials = creds; | |
// if(null != sender.) client.AddAuthInfo(username,password,authInfo); | |
if (sender.AlwaysSendBasicAuthHeader) webRequest.AddBasicAuth(sender.UserName, sender.Password); | |
if (!sender.DisableAutoCompression) | |
{ | |
webRequest.Headers.Add(HttpRequestHeader.AcceptEncoding, "gzip,deflate"); | |
webRequest.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate; | |
} | |
if (sender.StoreCookies) | |
{ | |
webRequest.CookieContainer = sender.CookieContainer; | |
} | |
webRequest.AllowAutoRedirect = sender.AllowAutoRedirect; | |
// ignore requestwebfilter | |
webRequest.ContentType = sender.ContentType; | |
} | |
catch (Exception ex) | |
{ | |
throw new Exception("PortFilesWithRequest", ex); | |
} | |
var queryString = QueryStringSerializer.SerializeToString(request); | |
var nameValueCollection = HttpUtility.ParseQueryString(queryString); | |
var boundary = DateTime.UtcNow.Ticks.ToString(CultureInfo.InvariantCulture); | |
webRequest.ContentType = "multipart/form-data; boundary=" + boundary; | |
boundary = "--" + boundary; | |
var newLine = "\r\n"; | |
using (var outputStream = webRequest.GetRequestStream()) | |
{ | |
foreach (var key in nameValueCollection.AllKeys) | |
{ | |
outputStream.Write(boundary + newLine); | |
outputStream.Write("Content-Disposition: form-data;name=\"{0}\"{1}".FormatWith(key, newLine)); | |
outputStream.Write("Content-Type: text/plain;charset=utf-8{0}{1}".FormatWith(newLine, newLine)); | |
outputStream.Write(nameValueCollection[key] + newLine); | |
} | |
foreach (var file in files) | |
{ | |
writeFileStream(outputStream, file, boundary, newLine); | |
} | |
outputStream.Write(boundary + "--"); // Finalize boundary | |
} | |
return webRequest; | |
}; | |
// The execution | |
try | |
{ | |
var webRequest = createWebRequest(); | |
var webResponse = webRequest.GetResponse(); | |
if (webResponse is HttpWebResponse) | |
{ | |
if (ServiceClientBase.HttpWebResponseFilter != null) | |
ServiceClientBase.HttpWebResponseFilter((HttpWebResponse)webResponse); | |
if (sender.LocalHttpWebResponseFilter != null) | |
sender.LocalHttpWebResponseFilter((HttpWebResponse)webResponse); | |
} | |
return HandleResponse<TResponse>(sender, webResponse); | |
} | |
catch (Exception ex) | |
{ | |
throw new Exception("Can not PostFilesWithRequest", ex); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment