Отправить сырой JSON и файл в той же конечной точке веб-API 2

0

Мне было интересно, можно ли отправить файл (который мне нужен только ".pdf", ".jpg" или ".png") вместе с сырым JSON. Все мои конечные точки до сих пор отправляют raw JSON (который я тестирую через Postman, поскольку интерфейс еще не существует), предполагается, что отправка данных формы будет отправляться с использованием Angular Js. Я еще не знаю Angular Js, поэтому я не могу представить, как это будет работать.

Подпись конечной точки выглядит следующим образом:

[Route("Post")]
    [CustomAuthorize(Roles = "User, Admin")]
    [ValidateJWT]
    public async Task<IHttpActionResult> Post(HttpRequestMessage request, SalesOrderViewModel orderData)

Модель представления - это просто класс aС# с множеством свойств строки, которые конвертирует модель из JSON.

Я хотел бы знать, возможна ли отправка сырого JSON и файла, который пользователь будет выбирать, в той же конечной точке с помощью Web API 2. Это?

Заранее спасибо.

Теги:
asp.net-web-api

2 ответа

1

Изменить: просто проверено, что вам не нужно использовать IEnumerable<byte>. Использование byte[] отлично работает.


WebApi поддерживает десериализацию массива JSON для IEnumerable<T>, так что вы можете получать байты, объявляя с помощью IEnumerable<byte>.

В следующем примере показано, как загрузить изображение:

public class ImageModel
{
    public string Name { get; set; }
    public IEnumerable<byte> Bytes { get; set; }
}

В вашем контроллере. Запись изображения на диск:

private string WriteImage(byte[] arr)
{
    var filename = $@"images\{DateTime.Now.Ticks}.";

    using (var im = Image.FromStream(new MemoryStream(arr)))
    {
        ImageFormat frmt;
        if (ImageFormat.Png.Equals(im.RawFormat))
        {
            filename += "png";
            frmt = ImageFormat.Png;
        }
        else
        {
            filename += "jpg";
            frmt = ImageFormat.Jpeg;
        }
        string path = HttpContext.Current.Server.MapPath("~/") + filename;
        im.Save(path, frmt);
    }

    return $@"http:\\{Request.RequestUri.Host}\{filename}";
}

HttpContext.Current.Server.MapPath("~/") даст внутренний путь работы сервера. Request.RequestUri.Host возвращает имя хоста.

public IHttpActionResult UploadImage(ImageModel model)
{
    var imgUrl = WriteImage(model.Bytes.ToArray());

    // Some code
}

В HTML:

<input type="file" id="imageFile"/>

Метод загрузки для AngularJS:

$scope.upload = function () {

     var file = document.getElementById("imageFile").files[0];
     var r = new FileReader();
     r.onloadend = function (e) {


         var arr = Array.from(new Uint8Array(e.target.result));

         var uploadData = {
             Name: "Name of Image",
             Bytes: arr
         }
         console.log(uploadData);

         $http.post('api/Uploader/UploadImage', uploadData)
         .then(
         function (response) {
             console.log(response);
         },

         function (reason) {

             console.log(reason);
         })
     }
     r.readAsArrayBuffer(file);
 }
1

Вы не можете направлять сообщение с помощью asplication/json, но вы можете сделать это с помощью нескольких полей формы (в виде данных формы), файлов + данных, где значение данных может быть JSON.

Я не рекомендую этот метод, но трюк:

public async Task<IHttpActionResult> Post()
        {
            if (!Request.Content.IsMimeMultipartContent())
            {
                Request.CreateResponse(HttpStatusCode.UnsupportedMediaType);
            }

            //load in a memory stream or in azure blob storage
            var uploadFolder = "~/App_Data/FileUploads"; // to demonstrate the upload so please don't comment about where I'm saving the file, don't recommend this under no circumstance
            var root = HttpContext.Current.Server.MapPath(uploadFolder);
            Directory.CreateDirectory(root);
            var provider =  new MultipartFormDataStreamProvider(root);
            var result = await Request.Content.ReadAsMultipartAsync(provider);

            if (result.FileData.FirstOrDefault() == null)
            {
                return BadRequest("No import file was attached");
            }

            var uploadedFileInfo = new FileInfo(result.FileData.First().LocalFileName);

            var model = result.FormData["model"];

            if (model == null)
            {
                return BadRequest("Model is missing");
            }

            var parameters = JsonConvert.DeserializeObject<Coords>(model);

            var byteArray = File.ReadAllBytes(uploadedFileInfo.FullName);
           //..process the bytes
           //..process json passed in headers
}

И модель:

public class Coords
    {
        public Cord[] cords { get; set; }
    }

    public class Cord
    {
        public int x { get; set; }
        public object y { get; set; }
    }

Почтальон звонит:

Изображение 174551

  • 0
    Любая конкретная причина, по которой вы не рекомендуете этот подход (для отправки файлов и данных с помощью Form Post).
  • 0
    Поскольку вышеприведенный пример является гибридным подходом, вам необходимо десерилизовать заполненную форму модели, посмотрите, как выглядит сериализованный режим w3schools.com/jquery/…

Ещё вопросы

Сообщество Overcoder
Наверх
Меню