文件上传验证文件数据然后保存; MIME多部分流

时间:2018-02-10 06:57:33

标签: c# asp.net asp.net-web-api file-upload multipartform-data

问题

上周刚开始使用c#,所以我完全有可能错过了一些明显的东西。请帮忙。我对更好的方式持开放态度。

我正在创建一个WebAPI文件上传端点,它会推迟保存,直到确认文件的签名为止。


我在Postman中收到此错误:

  

“MIME多部分流的意外结束.MIME multipart消息未完成。”,


this stackoverflow answer,我收到错误,因为我开始第二个内存流,而第一个内存流仍然打开。

我的代码如下。

解决问题的努力:

我在过去两天尝试实施thisthis和其他许多人。

提出了一个类似的问题,没有答案,here

代码到目前为止

C#代码段在Stack Overflow中无法运行

我正在使用MultipartMemoryStreamProvider来创建流并获取文件签名。我创建了一个CustomMultipartMemoryStream来继承IDisposable接口:

查看CustomMultipartMemoryStreamProvider类

public class CustomMultipartMemoryStreamProvider : MultipartMemoryStreamProvider, IDisposable
{
    public void Dispose()
    {
    }
}


然后我创建一个using语句来启动CustomMultipartMemoryStream,获取签名,并确认文件是否是JPEG。然后我处理了流:

查看MultipartMemoryStreamProvider实施

bool isJpeg;

using (var MemoryStream = await Request.Content.ReadAsMultipartAsync(new CustomMultipartMemoryStreamProvider()))
{
    try
    {
        //Get Signatures works.
        //It uses Stream.Read to read the first 6 bytes of the stream
        //returns byte[]

        byte[] FileSignature = GetSignature(await MemoryStream.Contents[0].ReadAsStreamAsync());

        //HasJpegHeaders works.
        //It returns true or false
        isJpeg = HasJpegHeader(FileSignature);
    }
    finally
    {
        //This should dispose of the stream.
        //It runs.
        MemoryStream.Dispose();
    }

}

查看GetSignature(WORKS)

static byte[] GetSignature(Stream stream)
{
    int offset = 0;
    byte[] fileSignature = new byte[6];
    while (offset < 6)
    {

        int read = stream.Read(fileSignature, offset, 6 - offset);
        if (read == 0)
            throw new System.IO.EndOfStreamException();
        offset += read;
    }
    stream.Position = 0;


    return fileSignature;

}

查看HasJpegHeader(WORKS)

static bool HasJpegHeader(byte[] FileSignature)
{
    byte[] SoiArray = FileSignature.Take(2).ToArray();

    byte[] MarkerArray = FileSignature.Skip(2).Take(2).ToArray();

    bool result =  ((SoiArray.SequenceEqual(new byte[]{ 255, 216 })) &&     (MarkerArray.SequenceEqual(new byte[] { 255, 224 })));
    return result;
}


如果文件是jpeg,我会启动一个CustomMultipartFormDataStreamProvider,它与MultipartFormDataStreamProvider相同,只是它保存文件名。

await Request.Content.ReadAsMultipartAsync(provider)抛出错误 (用箭头标注。)

查看CustomMultipartFormDataStreamProvider

if (isJpeg)
{
    string fileSaveLocation = HttpContext.Current.Server.MapPath("~/App_Data");

    CustomMultipartFormDataStreamProvider provider = new CustomMultipartFormDataStreamProvider(fileSaveLocation);
    List<string> files = new List<string>();

    try
    {

here be error-->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);
    }

}
else
{
    return Request.CreateResponse(HttpStatusCode.NotAcceptable, "This request is not properly formatted");   
}

0 个答案:

没有答案