Asp.net MVC 应用程序无法托管且无法正常工作
Asp.net MVC application cannot be hosted and working properly
我遇到了一个至今没有解决的问题,我花了三周的时间来解决。我应该创建一个执行以下操作的 Web 应用程序:
1- 允许用户从下拉列表中 select 搜索条件并单击导出按钮。
2- 按钮单击事件调用 API,后者根据搜索条件依次从数据存储中获取数据,打开现有的 Excel 模板文件并用返回的数据填充它,然后保存使用新名称(即,原始模板名为 abc.xlsx,它将保存为 abc[date]-[time].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);
}
}
}
下面是 invoker.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 上 selected/installed:
Web Management Tools -> IIS Management Console
World Wide Web Services
Application Development Features -> .NET Extensibility 3.5, .NET Extensibility 4.7, ASP.NET 3.5, ASP.NET 4.7, CGI, ISAPI Extensions, ISAPI Filters
Common HTTP Features -> Default Document, Direct Browsing, HTTP Errors, Static Content
Health and Diagnostics -> HTTP Logging
Performance Features -> Static Content Compression
Security -> Request Filtering
我还授予了IIS_IUSERS/管理员对发布文件夹的完全控制权限IIS 网站定向.
我还为 Excel
配置了以下组件服务
Component Services -> Computers -> My Computer -> DCOM Config -> Microsoft
Excel Application -> Properties
Authentication Level -> None
Security
Launch and Activation Permissions** -> Customize ->
Administrators/IIS_IUSERS have full permissions
Access Permissions -> Customize -> Administrators/IIS_IUSERS have full
permissions
Configure Permissions -> Customize -> Administrators/IIS_IUSERS have full
permissions
我在打开现有的 Excel 模板文件模板时仍然遇到问题,因为我必须打开文件,用数据填充它,保存,阻止应用程序的其余步骤被执行给它一个新的名字,然后下载新创建的文件!
最后,我发现如果您托管通过 COM 使用 Microsoft Office 的应用程序,您总会遇到麻烦。我使用了基于 XML 的第三方 API 而不是 EPPlus,它对我来说效果很好,即使我不必在主机上安装 Microsoft Office。
我遇到了一个至今没有解决的问题,我花了三周的时间来解决。我应该创建一个执行以下操作的 Web 应用程序:
1- 允许用户从下拉列表中 select 搜索条件并单击导出按钮。 2- 按钮单击事件调用 API,后者根据搜索条件依次从数据存储中获取数据,打开现有的 Excel 模板文件并用返回的数据填充它,然后保存使用新名称(即,原始模板名为 abc.xlsx,它将保存为 abc[date]-[time].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);
}
}
}
下面是 invoker.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 上 selected/installed:
Web Management Tools -> IIS Management Console
World Wide Web Services
Application Development Features -> .NET Extensibility 3.5, .NET Extensibility 4.7, ASP.NET 3.5, ASP.NET 4.7, CGI, ISAPI Extensions, ISAPI Filters
Common HTTP Features -> Default Document, Direct Browsing, HTTP Errors, Static Content
Health and Diagnostics -> HTTP Logging
Performance Features -> Static Content Compression
Security -> Request Filtering
我还授予了IIS_IUSERS/管理员对发布文件夹的完全控制权限IIS 网站定向.
我还为 Excel
配置了以下组件服务Component Services -> Computers -> My Computer -> DCOM Config -> Microsoft
Excel Application -> Properties
Authentication Level -> None
Security
Launch and Activation Permissions** -> Customize ->
Administrators/IIS_IUSERS have full permissions
Access Permissions -> Customize -> Administrators/IIS_IUSERS have full
permissions
Configure Permissions -> Customize -> Administrators/IIS_IUSERS have full
permissions
我在打开现有的 Excel 模板文件模板时仍然遇到问题,因为我必须打开文件,用数据填充它,保存,阻止应用程序的其余步骤被执行给它一个新的名字,然后下载新创建的文件!
最后,我发现如果您托管通过 COM 使用 Microsoft Office 的应用程序,您总会遇到麻烦。我使用了基于 XML 的第三方 API 而不是 EPPlus,它对我来说效果很好,即使我不必在主机上安装 Microsoft Office。