-
Notifications
You must be signed in to change notification settings - Fork 176
Cookbook
You can receive multi-part request if you include this static method (from http://stackoverflow.com/questions/7460088/reading-file-input-from-a-multipart-form-data-post):
private static async Task ParseFiles(Stream data, string contentType, Action<string, Stream> fileProcessor)
{
var streamContent = new StreamContent(data);
streamContent.Headers.ContentType = MediaTypeHeaderValue.Parse(contentType);
var provider = await streamContent.ReadAsMultipartAsync();
foreach (var httpContent in provider.Contents)
{
var fileName = httpContent.Headers.ContentDisposition.FileName;
if (string.IsNullOrWhiteSpace(fileName))
{
continue;
}
using (var fileContents = await httpContent.ReadAsStreamAsync())
{
fileProcessor(fileName.Replace("\"", ""), fileContents);
}
}
}
You need to include WebApi Client Nuget.
Also you can check the HttpMultipartParser Nuget and connect the Request input directly to the HttpMultipartParser, very helpful and small.
I just wanted to share with you a random port choosing demo that I created for myself. Perhaps you will want to build this feature into your project one day, but the example below is working fine for me and it may serve as a helpful example for other readers.
The wrapper class (StaticWebServer
) is shown last. Here is how I now use it from my WinForms demo:
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
using (var webServer = new StaticWebServer())
{
webServer.RunAsync();
Application.Run(new Views.MainView(webServer.UsingBaseAddress));
}
}
...and in the main view:
public MainView(string webViewUrl = "about:blank")
{
InitializeComponent();
browser.Url = new Uri(webViewUrl);
mainStatusLabel.Text = "";
}
And finally, here is the StaticWebServer
class, which chooses the port to use dynamically:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Unosquare.Labs.EmbedIO;
using Unosquare.Labs.EmbedIO.Log;
using Unosquare.Labs.EmbedIO.Modules;
namespace YourOwnNamespace
{
class StaticWebServer : IDisposable
{
public StaticWebServer() { }
static Random _portGenerator = new Random();
static List<int> _portsUsed = new List<int>();
/// <summary>
/// An instance of the (awesome!) EmbedIO WebServer.
/// </summary>
WebServer _server;
/// <summary>
/// String format template to merge the randomly generated port into.
/// Default: "http://127.0.0.1:{0}/"
/// </summary>
public string BaseAddressTemplate { get; set; } = "http://127.0.0.1:{0}/";
public int PortRangeMin { get; set; } = 51001;
public int PortRangeMax { get; set; } = 65001;
/// <summary>
/// Relative or absolute path to serve static files from.
/// </summary>
public string RootFilesystemPath { get; set; } = "browse";
/// <summary>
/// The base address currently being used by the server.
/// </summary>
public string UsingBaseAddress { get; private set; }
/// <summary>
/// The port currently being used by the server.
/// </summary>
public int UsingPort { get; private set; }
/// <summary>
/// The root filesystem path currently being used by the server.
/// </summary>
public string UsingRootFilesystemPath { get; private set; }
WebServer CreateServer(string baseAddress, string rootPath)
{
var logger = new DebugLogger();
var server = new WebServer(baseAddress, logger);
var headers = new Dictionary<string, string>()
{
#if DEBUG
// The following is mostly useful for debugging.
{ Constants.HeaderCacheControl, "no-cache, no-store, must-revalidate" },
{ Constants.HeaderPragma, "no-cache" },
{ Constants.HeaderExpires, "0" }
#endif
};
var staticFileMod = new StaticFilesModule(rootPath, headers);
staticFileMod.DefaultExtension = ".html";
server.RegisterModule(staticFileMod);
return server;
}
string GetAbsoluteRootDirectoryPath()
{
if (Path.IsPathRooted(RootFilesystemPath))
return RootFilesystemPath;
var baseDir = Path.GetDirectoryName(
System.Reflection.Assembly.GetEntryAssembly()
.Location);
return Path.Combine(baseDir, RootFilesystemPath);
}
public void RunAsync()
{
UsingRootFilesystemPath = GetAbsoluteRootDirectoryPath();
Debug.Print("Serving static files from: {0}", UsingRootFilesystemPath);
// Random port selection adapted from http://stackoverflow.com/a/223188/16387
UsingPort = -1;
UsingBaseAddress = null;
while (true)
{
UsingPort = _portGenerator.Next(PortRangeMin, PortRangeMax);
if (_portsUsed.Contains(UsingPort))
continue;
UsingBaseAddress = String.Format(BaseAddressTemplate, UsingPort.ToString());
_server = CreateServer(UsingBaseAddress, UsingRootFilesystemPath);
try
{
_server.RunAsync();
} catch (System.Net.HttpListenerException)
{
_server.Dispose();
_server = null;
continue;
}
_portsUsed.Add(UsingPort);
break;
}
}
public void Dispose()
{
Dispose(true);
}
void Dispose(bool disposing)
{
if (!disposing)
return;
var server = _server;
_server = null;
if (server == null)
return;
server.Dispose();
}
#region DebugLogger
/// <summary>
/// Provides a simple logger for Debug output.
/// </summary>
class DebugLogger : ILog
{
private static void WriteLine(string format, params object[] args)
{
var d = DateTime.Now;
var dateTimeString = string.Format("{0}-{1}-{2} {3}:{4}:{5}.{6}",
d.Year.ToString("0000"), d.Month.ToString("00"), d.Day.ToString("00"), d.Hour.ToString("00"),
d.Minute.ToString("00"), d.Second.ToString("00"), d.Millisecond.ToString("000"));
format = dateTimeString + "\t" + format;
if (args != null)
Debug.Print(format, args);
else
Debug.Print(format);
}
public virtual void Info(object message)
{
InfoFormat(message.ToString(), null);
}
public virtual void Error(object message)
{
ErrorFormat(message.ToString(), null);
}
public virtual void Error(object message, Exception exception)
{
ErrorFormat(message.ToString(), null);
ErrorFormat(exception.ToString(), null);
}
public virtual void InfoFormat(string format, params object[] args)
{
WriteLine(format, args);
}
public virtual void WarnFormat(string format, params object[] args)
{
WriteLine(format, args);
}
public virtual void ErrorFormat(string format, params object[] args)
{
WriteLine(format, args);
}
public virtual void DebugFormat(string format, params object[] args)
{
WriteLine(format, args);
}
}
#endregion
}
}