ASP.NET Как читать данные с несколькими частями в веб-API?

Я отправляю данные мультипартийной формы в свой веб-API следующим образом:

string example = "my string";
HttpContent stringContent = new StringContent(example);
HttpContent fileStreamContent = new StreamContent(stream);
using (var client = new HttpClient())
{
    using (var content = new MultipartFormDataContent())
    {
         content.Add(stringContent, "example", "example");
         content.Add(fileStreamContent, "stream", "stream");
         var uri = "http://localhost:58690/api/method";
         HttpResponseMessage response = await client.PostAsync(uri, content);

и это веб-API:

[HttpPost]
[Route("api/method")]
public async Task<HttpResponseMessage> Method()
    {
         // take contents and do something
    }

Как читать строку и поток из тела запроса в моем веб-API?

Ответ 1

Это поможет вам начать:

 var uploadPath = HostingEnvironment.MapPath("/") + @"/Uploads";
 Directory.CreateDirectory(uploadPath);
 var provider = new MultipartFormDataStreamProvider(uploadPath);
 await Request.Content.ReadAsMultipartAsync(provider);

 // Files
 //
 foreach (MultipartFileData file in provider.FileData)
 {
     Debug.WriteLine(file.Headers.ContentDisposition.FileName);
     Debug.WriteLine("File path: " + file.LocalFileName);
 }

 // Form data
 //
 foreach (var key in provider.FormData.AllKeys)
 {
     foreach (var val in provider.FormData.GetValues(key))
     {
          Debug.WriteLine(string.Format("{0}: {1}", key, val));
     }
 }

Ответ 2

Это код, который я использовал ранее, чтобы получать данные json + дополнительный файл:

var result = await Request.Content.ReadAsMultipartAsync();

var requestJson = await result.Contents[0].ReadAsStringAsync();
var request = JsonConvert.DeserializeObject<MyRequestType>(requestJson);

if (result.Contents.Count > 1)
{
    var fileByteArray = await result.Contents[1].ReadAsByteArrayAsync();
    ...
}

Он действительно опрятен тем, что вы можете комбинировать различные типы данных в запросе, подобном этому.

Изменить: пример отправки этого запроса:

let serialisedJson = JSON.stringify(anyObject);
let formData = new FormData();
formData.append('initializationData', serialisedJson);
// fileObject is an instance of File
if (fileObject) {
    // the 'jsonFile' name might cause some confusion: 
    // in this case, the uploaded file is actually a textfile containing json data
    formData.append('jsonFile', fileObject);
}

return new Promise((resolve, reject) => {
    let xhr = new XMLHttpRequest();
    xhr.open('POST', 'http://somewhere.com', true);
    xhr.onload = function(e: any) {
        if (e.target.status === 200) {
            resolve(JSON.parse(e.target.response));
        }
        else {
            reject(JSON.parse(e.target.response));
        }
    };
    xhr.send(formData);
});

Ответ 3

Вы можете прочитать содержимое и получить всю информацию о файле (в моем примере изображения) без копирования на локальный диск следующим образом:

public async Task<IHttpActionResult> UploadFile()
{
    if (!Request.Content.IsMimeMultipartContent())
    {
        return StatusCode(HttpStatusCode.UnsupportedMediaType);
    }        

    var filesReadToProvider = await Request.Content.ReadAsMultipartAsync();

    foreach (var stream in filesReadToProvider.Contents)
    {
        // Getting of content as byte[], picture name and picture type
        var fileBytes = await stream.ReadAsByteArrayAsync();
        var pictureName = stream.Headers.ContentDisposition.FileName;
        var contentType = stream.Headers.ContentType.MediaType;
    }
}

Ответ 4

Для отправки более одного файла

        System.Web.HttpFileCollection hfc = System.Web.HttpContext.Current.Request.Files;

        //// CHECK THE FILE COUNT.
        for (int iCnt = 0; iCnt <= hfc.Count - 1; iCnt++)
        {
            System.Web.HttpPostedFile hpf = hfc[iCnt];
            string Image = UploadDocuments.GetDocumentorfileUri(hpf);
            UploadDocuments.UploadDocumentsIntoData(Image, hpf.FileName, id);

        }

Отправка данных формы HTML в веб-API ASP.NET: загрузка файлов и многостраничный MIME

Ответ 5

 // read the file content without copying to local disk and write the content byte to file 
       try
       {
           var filesReadToProvider = await Request.Content.ReadAsMultipartAsync();
           JavaScriptSerializer json_serializer = new JavaScriptSerializer();

           foreach (var stream in filesReadToProvider.Contents)
           {

               //getting of content as byte[], picture name and picture type
               var fileBytes = await stream.ReadAsByteArrayAsync();
               var fileName = stream.Headers.ContentDisposition.Name;

               var pictureName = stream.Headers.ContentDisposition.FileName;
               var contentType = stream.Headers.ContentType.MediaType;
               var path = Path.Combine(HttpContext.Current.Server.MapPath("~/Images/Upload/"), json_serializer.Deserialize<string>(pictureName));

               File.WriteAllBytes(path, fileBytes);
           }

           return Request.CreateResponse(HttpStatusCode.OK);
       }catch(Exception ex)
       {
           return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, ex);
       }

Ответ 6

//Метод пользовательского веб-интерфейса защищен void btnPrescAdd_Click (отправитель объекта, EventArgs e) {

        NameValueCollection collection = new NameValueCollection();

        collection.Set("c1", Session["CredID"].ToString());
        collection.Set("p1", "");
        collection.Set("p2", Request.Form["ctl00$MainContent$hdnHlthId"]);
        collection.Set("p3", Request.Form["ctl00$MainContent$PresStartDate"]);
        collection.Set("p4", Request.Form["ctl00$MainContent$PrescEndDate"]);

        FileUpload fileUpload = PrescUpload;

        ApiServices<Status> obj = new ApiServices<Status>();
        Status objReturn = obj.FetchObjectUploadAPI("POSTUHRPL", collection, 
         fileUpload, ApiServices<Status>.ControllerType.DU);

    }

//Метод запроса

  public T1 FetchObjectUploadAPI(string strAPIMethod, NameValueCollection collection, FileUpload file, ControllerType enObj)
    {
        T1 objReturn;
        try
        {
            string url = strWebAPIUrl + getControllerName(enObj) + strAPIMethod;

            MultipartFormDataContent content = new MultipartFormDataContent();



            int count = collection.Count;
            List<string> Keys = new List<string>();
            List<string> Values = new List<string>();

            //MemoryStream filedata = new MemoryStream(file);
            //Stream  stream = filedata;
            for (int i = 0; i < count; i++)
            {
                Keys.Add(collection.AllKeys[i]);
                Values.Add(collection.Get(i));

            }

            for (int i = 0; i < count; i++)
            {
                content.Add(new StringContent(Values[i], Encoding.UTF8, "multipart/form-data"), Keys[i]);
            }

            int fileCount = file.PostedFiles.Count();

            HttpContent filecontent = new StreamContent(file.PostedFile.InputStream);


            content.Add(filecontent, "files");

            HttpClient client = new HttpClient();


            HttpResponseMessage response = client.PostAsync(url, content).Result;

            if (response.IsSuccessStatusCode)
            {
                objReturn = (new JavaScriptSerializer()).Deserialize<T1>(response.Content.ReadAsStringAsync().Result);
            }
            else
                objReturn = default(T1);

        }
        catch (Exception ex)
        {
            Logger.WriteLog("FetchObjectAPI", ex, log4net_vayam.Constants.levels.ERROR);
            throw (ex);
        }
        return objReturn;

    }

https://stackoverflow.com/users/9600164/gaurav-sharma