1.自主宿主HttpSelfHost的实现
#region Web Api监听
Assembly.Load("Lind.DDD.TestApi"); //手工加载某个api程序集的controller
var config = new HttpSelfHostConfiguration("http://localhost:3333");
config.Routes.MapHttpRoute("default", "api/{controller}/{id}", new { id = RouteParameter.Optional });
var server = new HttpSelfHostServer(config);
server.OpenAsync().Wait();
Console.WriteLine("Server is opened");
#endregion
也可使用如下方式注册路由
public class RouteConfig
{
public static void RegisterRoutes(HttpRouteCollection httpRouteCollection)
{
httpRouteCollection.MapHttpRoute( //配置路由
"API Default", "api/{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = RouteParameter.Optional });
}
}
其中的config可以进行配置
public class HttpSelfHostConfiguration : HttpConfiguration
{
public HttpSelfHostConfiguration(string baseAddress);
public HttpSelfHostConfiguration(Uri baseAddress);
public Uri BaseAddress { get; }
public HttpClientCredentialType ClientCredentialType { get; set; }
public HostNameComparisonMode HostNameComparisonMode { get; set; }
public int MaxBufferSize { get; set; }
public int MaxConcurrentRequests { get; set; }
public long MaxReceivedMessageSize { get; set; }
public TimeSpan ReceiveTimeout { get; set; }
public TimeSpan SendTimeout { get; set; }
public TransferMode TransferMode { get; set; }
public System.IdentityModel.Selectors.UserNamePasswordValidator UserNamePasswordValidator { get; set; }
public System.IdentityModel.Selectors.X509CertificateValidator X509CertificateValidator { get; set; }
protected virtual BindingParameterCollection OnConfigureBinding(HttpBinding httpBinding);
}
config.MaxReceivedMessageSize = int.MaxValue;
config.TransferMode = TransferMode.Buffered;
上述两项配置可以实现不限制文件大小上传。
2. 实现上传功能的WebApi
[HttpPost]
public RestResult Upload()
{
if (!Request.Content.IsMimeMultipartContent())
{
throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
}
try
{
var provider = new MultipartFormDataStreamProvider(PacsEnvironment.PacsTemperature);
var task = Request.Content.ReadAsMultipartAsync(provider);
task.Wait();
foreach (var f in provider.FileData)
{
Logger.ErrorWithFormat("filename:{0}", f.Headers.ContentDisposition.FileName);
Logger.ErrorWithFormat("{0}", f.LocalFileName);
}
return "";
}
catch (System.Exception e)
{
return "";
}
return "";
}
测试工程:
class Program
{
static void Main(string[] args)
{
string fileName = string.Empty;
while (true)
{
Console.Write("input:");
fileName = Console.ReadLine();
if (!File.Exists(fileName))
continue;
WebClient client = new WebClient();
byte[] bytes = client.UploadFile("http://ip:端口/api/Image/UploadAndStoreDicom", fileName);
string str = System.Text.Encoding.UTF8.GetString(bytes);
Console.WriteLine(str);
}
}
}
网上比较完整的用法
public class vUploadController : ApiController
{
public async Task<HttpResponseMessage> Post()
{
//检查POST的是否为MultiPart
if(!Request.Content.IsMimeMultipartContent())
{
throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
}
//准备CustomMultipart格式的数据流的提供者
//数据将会被加载
string fileSaveLocation = HttpContext.Current.Server.MapPath("~/App_Data");
CustomMultipartFormDataStreamProvider provider = new CustomMultipartFormDataStreamProvider(fileSaveLocation);
List<string> files = new List<string>();
try
{
// Read all contents of multipart message into CustomMultipartFormDataStreamProvider.
await Request.Content.ReadAsMultipartAsync(provider);
foreach (MultipartFileData file in provider.FileData)
{
files.Add(Path.GetFileName(file.LocalFileName));
}
// Send OK Response along with saved file names to the client.
return Request.CreateResponse(HttpStatusCode.OK, files);
}
catch (System.Exception e)
{
return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, e);
}
}
}
// We implement MultipartFormDataStreamProvider to override the filename of File which
// will be stored on server, or else the default name will be of the format like Body-
// Part_{GUID}. In the following implementation we simply get the FileName from
// ContentDisposition Header of the Request Body.
public class CustomMultipartFormDataStreamProvider : MultipartFormDataStreamProvider
{
public CustomMultipartFormDataStreamProvider(string path) : base(path) { }
public override string GetLocalFileName(HttpContentHeaders headers)
{
return headers.ContentDisposition.FileName.Replace("\"", string.Empty);
}
}
不存文件到服务器的方式(鸡肋,存了我也可以删除)
下面的代码直接从请求的Content中读取请求数据,得到MultipartMemoryStreamProvider对象,遍历该对象的Contents属性,可以得到包含上传文件及form表单数据的HttpContent对象。如何从Contents找到包含文件数据的HttpContent对象,可以根据HttpContent对象头部中对应的FileName属性来判断,这个需要和前端约定好,文件数据必须传入文件名称。
var multipartMemoryStreamProvider = await Request.Content.ReadAsMultipartAsync();
Dictionary<string, string> dic = new Dictionary<string, string>();
foreach (var content in multipartMemoryStreamProvider.Contents)
{
if (!string.IsNullOrEmpty(content.Headers.ContentDisposition.FileName))
{
using (Stream stream = await content.ReadAsStreamAsync())
{
byte[] bytes = new byte[stream.Length];
stream.Read(bytes, 0, bytes.Length);
}
}
else
{
string val = await content.ReadAsStringAsync();
dic.Add(content.Headers.ContentDisposition.Name, val);
}
}