Загрузка 0-байтовых изображений - C#. NET Core и Asyn c проблемы - PullRequest
1 голос
/ 06 марта 2020

Я видел, как эта проблема возникла по другим вопросам, и, пожалуйста, поверьте мне, я пробовал так много вещей, чтобы это работало. Когда я нахожусь в режиме отладки, я могу загрузить изображение и заставить его отлично отображаться, но как только оно будет запущено, все, что я получу, - это пустое, 0-байтовое изображение. Я попытался сделать всю задачу asyn c, включил команды await, сбросил позицию потока и попробовал контейнер BLOB-объектов Azure. Что я делаю неправильно? Веб-приложение размещено на Azure.

Controller, CategoriesController.cs

        [Route("save")]
        [HttpPost]
        public async Task<IActionResult> Save(SaleItem item, IFormFile photo)
        {
            if (item.AccessValidation == 000)
            {
                if (photo == null || photo.Length == 0)
                {
                    item.ImgURL = string.Empty;
                }
                else
                {
                    var path = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot/data/images", photo.FileName);
                    var stream = new FileStream(path, FileMode.Create);
                    await photo.CopyToAsync(stream).ConfigureAwait(true);
                    stream.Seek(0, SeekOrigin.Begin);
                    stream.Close();
                    item.ImgURL = photo.FileName;
                }
                item.AccessValidation = 1;
                WriteXML(item);
                return View("Success");
            }
            else
            {
                return Content("Invalid item submission!");
            }
        }

Просмотр, Post.cs html

<form asp-action="save" method="post" enctype="multipart/form-data">
    <div class="grid-x grid-padding-x">
        <div class="cell large-8">
            <label>Item Description</label>
            <input type="text" id="itemDescription" asp-for="Description" />
        </div>
        <div class="cell large-4">
            <input type="submit" class="button large right" value="Save to Inventory" />
        </div>
    </div>

На этот вопрос ответили - если кто-нибудь ищет это в будущем и хочет знать, как я его реализовал, вот что мне нужно изменить: Controller, CategoriesController.cs

using Microsoft.AspNetCore.Hosting; //add this reference
namespace Home.Move.Inventory.Controllers
{
    public class CategoriesController : Controller
    {
        private readonly IWebHostEnvironment _env;
        public CategoriesController(IWebHostEnvironment env)
        {
            _env = env;
        }
        [Route("save")]
        [HttpPost]
        public async Task<IActionResult> Save(SaleItem item, IFormFile photo)
        {
            if (item.AccessValidation == 0000)
            {
                if (photo == null || photo.Length == 0)
                {
                    item.ImgURL = string.Empty;
                }
                else
                {

                    var path = Path.Combine(_env.ContentRootPath, "wwwroot/data/images", photo.FileName);
                    var stream = new FileStream(path, FileMode.Create);
                    await photo.CopyToAsync(stream).ConfigureAwait(true);
                    stream.Seek(0, SeekOrigin.Begin);
                    stream.Close();
                    item.ImgURL = photo.FileName;
                }
                item.AccessValidation = 1;
                WriteXML(item);
                return View("Success");
            }
            else
            {
                return Content("Invalid item submission!");
            }

        }
}

Мне также пришлось обновить другие ссылки на путь содержимого - мне кажется, я использовал его в некоторых областях, но не в других, в основном из-за недостатка опыта. Я понимаю, что то, что я сделал здесь, было инъекцией зависимостей, и имело смысл использовать это последовательно как _env во всем классе.

1 Ответ

3 голосов
/ 06 марта 2020

Я думаю, что проблема в вас. Path.

Directory.GetCurrentDirectory () будет работать на локальном компьютере, но большинство пользователей сталкиваются с проблемой на производстве.

Использование environment.ContentRootPath вместо Directory.GetCurrentDirectory ()

Чтобы заставить Directory.GetCurrentDirectory () работать, нам нужно установить текущую работу для всего процесса w3wp.exe в каталог вашего приложения. После изменения текущего каталога, если IIS пытается загрузить модуль лениво или другой модуль IIS использует текущий рабочий каталог C: \ Windows \ System32 \ inetsrv, это может привести к сбою, который может или не может быть восстановлен.

То, как мы размещаем ANCM In-Process, аналогично System.Web (внутри процесса w3wp). System.Web также имеет Directory.GetCurrentDirectory () как C: \ Windows \ System32 \ inetsrv.

В качестве обходного пути мы установили Content Root как каталог приложения в Configuration. В любом месте, где вы можете разрешить IConfiguration, вы можете использовать IConfiguration [HostDefaults.ContentRootKey] для получения каталога приложения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...