Amr Mohammad Rashad Ответов: 2

Asp.net приложение MVC не может быть размещено и работать должным образом


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

1 - разрешить пользователю выбрать критерии поиска из выпадающего списка и нажать кнопку Экспорт.
2 - события нажатия кнопки, вызовы API, который в свою очередь получает данные из хранилища данных на основе критериев поиска, открывает существующий файл шаблона Excel и заполнить его с возвращаемых данных, и сохранить его с новым именем (я.е, оригинальный шаблон под названием abc.xlsx и он будет сохранен как дважды два[дата]-[время].XLSX-файл).
3 - Наконец загрузите только что созданный файл Excel.

Я создал приложение, и в среде разработки оно успешно выполнило первые два шага, когда я устал развертывать приложение либо на моей локальной машине IIS, либо на производственном сервере IIS приложение выполнило только первый шаг и часть второго (т. е. извлечение данных из хранилища данных), однако остальные шаги не могут быть выполнены. Вот мой код:

$("#dataexporter").click(function () {
        if ($("#countrycriteria").val().toString() === "0" || $("#productcriteria").val().toString() === "0") {
            $('from').append('<div class="alert alert-warning" role="alert">Please make sure you select all required fields!</div >');
        }
        else {
            $('div[class*="alert-warning"]').remove();
            $(this).prop('disabled', true);
            $.ajax("api/exportify/export?countrycriteria=" + $("#countrycriteria").val().toString() + "&productcriteria=" + $("#productcriteria").val().toString(), {
                type: "GET",
                contentType: "application/json; charset=utf-8",
                success: function (response, textStatus, jqXHR) {
                    if (response !== null)
                        window.location.href = JSON.parse(response).downloadurl

                    $(this).prop('disabled', false);
                },
                error: function (jqXHR, textStatus, errorThrown) {
                    alert('An error occurred ' + errorThrown);
                    $(this).prop('disabled', false);
                }
            });
        }
    });


[RoutePrefix("api/exportify")]
    public class ExportController : BaseController
    {
        private IExporterProvider provider;
        private Invoker invoker;

        public ExportController()
        {
            switch (AppConfiguration.ExporterProvider)
            {
                case "excel":
                    provider = new ExcelExporterProvider();
                    break;
                default:
                    throw new NotImplementedException();
            }

            invoker = new Invoker();
            invoker.Commands.Add(provider.GetExporter());
        }

private IEnumerable<Analytics> GetData(string countrycriteria, string productcriteria)
        {
            return helper.SelectByCountryAndProduct(countrycriteria, productcriteria);
        }

        private Dictionary<string, object> GetResponseContent()
        {
            string fname = AppConfiguration.SaveAsName;
            int lastBackslash = fname.LastIndexOf("\\");
            int substringLength = fname.Length - lastBackslash;
            string filename = fname.Substring(lastBackslash + 1, substringLength - 1);

            return new Dictionary<string, object> {
                { "downloadurl", Path.Combine(AppConfiguration.ServerAddress, AppConfiguration.Temporaryfolder, filename + AppConfiguration.FileExtension) }
            };
        }

        [HttpGet]
        [Route("export")]
        public IHttpActionResult Export(string countrycriteria, string productcriteria)
        {
            try
            {
                List<Analytics> data = (List<Analytics>)GetData(countrycriteria, productcriteria);
                if (data.Count > 0)
                {
                    data.ForEach(d => DeterminetheCategory(d));

                    foreach (var Command in invoker.Commands)
                    {
                        Command.ExportedData = data;
                    }

                    invoker.Execute();

                    return Ok(JsonConvert.SerializeObject(GetResponseContent()));
                }
                else
                {
                    return Content(HttpStatusCode.NoContent, string.Empty);
                }
            }
            catch (Exception e)
            {
                return Content(HttpStatusCode.InternalServerError, e);
            }
        }
}


Вот код, который в конечном итоге будет выполнен при вызове.Execute(); попадание в оператор:

public class ExcelExporter
    {
        protected static void ExportToExcel(IEnumerable<Analytics> data)
        {
            if (!File.Exists(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, AppConfiguration.Temporaryfolder, AppConfiguration.Filename + AppConfiguration.FileExtension)))
            {
                throw new FileNotFoundException("File Not Found.\nThe requested analytical.xlsx was not found on the server");
            }

            Microsoft.Office.Interop.Excel.Application xlsx = new Microsoft.Office.Interop.Excel.Application();
            Workbook workbook = null;
            Worksheet worksheet = null;

            try
            {
                workbook = xlsx.Workbooks.Open(
                Filename: Path.Combine(AppDomain.CurrentDomain.BaseDirectory, AppConfiguration.Temporaryfolder, AppConfiguration.Filename + AppConfiguration.FileExtension),
                ReadOnly: false);
                worksheet = (Worksheet)workbook.Worksheets[1];
                List<Analytics> list = (List<Analytics>)data;

                for (int i = 0; i < list.Count; i++)
                {
                    worksheet.Range[string.Format("A{0}", i + 2)].Value = list[i].ProductShare;
                    worksheet.Range[string.Format("B{0}", i + 2)].Value = list[i].MarketPotential;
                    worksheet.Range[string.Format("C{0}", i + 2)].Value = list[i].RepresnentativeName;
                    worksheet.Range[string.Format("D{0}", i + 2)].Value = list[i].DoctorName;
                    worksheet.Range[string.Format("E{0}", i + 2)].Value = list[i].CustomerCode;
                    worksheet.Range[string.Format("F{0}", i + 2)].Value = list[i].Specialization;
                    worksheet.Range[string.Format("G{0}", i + 2)].Value = list[i].ProductName;
                    worksheet.Range[string.Format("H{0}", i + 2)].Value = list[i].Category;
                }
            }
            catch (Exception e)
            {
                throw new Exception("Error while processing file", e);
            }
            finally
            {
                AppConfiguration.SaveAsName = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, AppConfiguration.Temporaryfolder, AppConfiguration.Filename + DateTime.Now.ToString("yyyyMMdd-hhmmss"));
                workbook.SaveAs(Filename: AppConfiguration.SaveAsName, FileFormat: XlFileFormat.xlOpenXMLWorkbook);
                workbook.Close(SaveChanges: true);
                xlsx.Quit();
                Marshal.ReleaseComObject(worksheet);
                Marshal.ReleaseComObject(workbook);
                Marshal.ReleaseComObject(xlsx);
            }
        }
    }


Вот как выбираются/устанавливаются функции IIS либо на моей локальной машине IIS, либо на рабочем сервере IIS:

* Инструменты Веб-Управления - консоль управления IIS>
* Услуги Всемирной Паутины
1 - Особенности Разработки Приложений -> .NET Extensibility 3.5, .NET Extensibility 4.7, ASP.NET 3.5, ASP.NET 4.7, CGI, расширения ISAPI, фильтры ISAPI
2 - общие функции HTTP -> документ по умолчанию, прямой просмотр, ошибки HTTP, статический контент
3 - здоровье и диагностика -> HTTP Logging
4 - Характеристики -> статическое сжатие контента
5 - безопасность -> фильтрация запросов

Я также дал обоим IIS_IUSERS и Администраторы полный контроль разрешений на папку публикации, на которую направлен веб-сайт IIS.

Я также настроил следующие службы компонентов для Excel
Службы компонентов -и gt; Инструменты -&ГТ; Мой компьютер -&ГТ; настройка DCOM -и gt; Приложения -&Майкрософт эксель gt; Свойства
уровень проверки подлинности -> Нет
Безопасность
1 - разрешения на запуск и активацию -> настройка -> администраторы/IIS_IUSERS имеют полные разрешения
2 - Права Доступа -> настройка -> администраторы/IIS_IUSERS имеют полные разрешения
3 - Настройка Разрешений -> настройка -> администраторы/IIS_IUSERS имеют полные разрешения

У меня все еще возникают проблемы, начиная с открытия существующего шаблона шаблона Excel, который блокирует выполнение остальных шагов приложения, так как я должен открыть файл, заполнить его данными, сохранить его с новым именем, а затем загрузить вновь созданный файл!.

Что я уже пробовал:

Поиск в интернете и применение некоторых решений, таких как настройка службы компонентов DCOM для приложения Excel, предоставление полных разрешений безопасности для папки публикации веб-сайта для пользователей/администраторов IIS_I

2 Ответов

Рейтинг:
11

Amr Mohammad Rashad

Проблема была решена все что мне нужно это установить Службы компонентов -и gt; Инструменты -&ГТ; Мой компьютер -&ГТ; настройка DCOM -и gt; Приложения -&Майкрософт эксель gt; Свойства -&ГТ; идентичность к интерактивный пользователь и украсьте класс, который использует COM-компонент, Экселэкспортер, с [ComVisible(true)] атрибут


Рейтинг:
1

F-ES Sitecore

Автоматизация офисных приложений, таких как Excel, не поддерживается в IIS, вы просто не сможете заставить это работать. Используйте альтернативу, которая поддерживается для asp.net например, драйвер OLEDB, XML SDK или сторонние приложения, такие как EPPlus и т. д.


Amr Mohammad Rashad

Ваше решение кажется мне нелогичным! почему? поскольку он работал один раз на моей локальной машине и на сервере, я просто столкнулся с проблемой, как я собираюсь направить браузер к недавно созданному файлу Excel для загрузки. Я только что установил новую копию операционной системы и не помню, что я делал раньше и чего мне может не хватать!. Большое спасибо за ваше время и внимание!

F-ES Sitecore

Есть много и много вещей, которые будут работать на вашем локальном компьютере, которые не будут работать при развертывании на удаленном сервере. Эти проблемы обычно возникают из-за того, что на вашей локальной машине ваш клиент и сервер одинаковы, но после удаленного доступа у вас есть только сервер, и все, что работало только на вашей локальной машине из-за конфигурации клиента, больше не работает.

Даже если этот код иногда работает или вы заставляете его работать, я гарантирую, что он будет ненадежным, перестанет работать после, возможно, 100 запросов, оставит сотни осиротевших процессов excel до тех пор, пока ваш сервер не перестанет отвечать. Что для меня нелогично, так это то, почему люди думают, что настольное приложение может быть автоматизировано с помощью службы, которая не имеет доступа к рабочему столу.

Игнорируйте это решение и используйте лучшее.

Amr Mohammad Rashad

Again I appreciate your consideration and your time for taking a look at my lengthy question and trying to help me!. At first, as I mentioned, the application was working but I was returning the file as array of bytes, however, I am a newbie to web development and I do not know much about it, I was unable to create a blob from the returning array of bytes using Javascript. So I figured out that if I can direct the browser using "ip/folder/file" that the browser download the created file from the server. Now each time the execution enters the finally block, specifically at the following line: workbook.SaveAs(Filename: AppConfiguration.SaveAsName, FileFormat: XlFileFormat.xlOpenXMLWorkbook); an exception being thrown: "ClassName": "System.NullReferenceException",
"Сообщение": "ссылка на объект не установлена на экземпляр объекта.",
"Данные": null,
"InnerException": null,
"HelpURL": null,
"StackTraceString": " at WebDataExporter.WebCore.Core.ExcelExporter.ExportToExcel(IEnumerable`1 data) in E:\\Demo\\WebDataExporter\\WebDataExporter.WebCore\\Core\\Adaptee\\ExcelExporter.cs:line 48\r\n at WebDataExporter.WebCore.Core.ExcelDataExporter.Export() in E:\\Demo\\WebDataExporter\\WebDataExporter.WebCore\\Core\\Adapter\\ExcelDataExporter.cs:line 11\r\n at WebDataExporter.WebCore.Core.Invoker.Execute() in E:\\Demo\\WebDataExporter\\WebDataExporter.WebCore\\Core\\Invoker.cs:line 18\r\n at WebDataExporter.WebCore.Controllers.ExportController.Export(String countrycriteria, String productcriteria) in E:\\Demo\\WebDataExporter\\WebDataExporter.WebCore\\Controllers\\ExportController.cs:line 78",
"RemoteStackTraceString": null,
"RemoteStackIndex": 0,
"ExceptionMethod": "8\nExportToExcel\nWebDataExporter.WebCore, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null\nWebDataExporter.WebCore.Core.ExcelExporter\nVoid ExportToExcel(System.Коллекции.Общий.IEnumerable`1[WebDataExporter.Модель.Аналитика])",
"Метод": -2147467261,
"Источник": "WebDataExporter.WebCore",
"Уотсонбакетс": ноль