WebApi的文件上传功能实现

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/weixin_41556165/article/details/83743811

 

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);
    }      
}

猜你喜欢

转载自blog.csdn.net/weixin_41556165/article/details/83743811