在webservice中此时不能启动异步操作



我有一个使用PuppeteerSharp将html转换为pdf的web服务,但是这一行

await new BrowserFetcher().DownloadAsync(BrowserFetcher.DefaultChromiumRevision);

返回这个错误

异步操作此时无法启动。异步操作只能在异步处理程序或模块中启动,或者在Page生命周期中的某些事件期间启动。如果在执行页面时发生此异常,请确保页面标记为<%@ Page Async="true"%祝辞。此异常也可能表明尝试调用async void;方法,在ASP中通常不支持。. NET请求处理。相反,异步方法应该返回一个Task,调用者应该等待它。

我代码:

[WebMethod]
public string HtmlToPdf(string htmlString, string baseURL, int anchoPagina, string tamanoPagina, string orientacionPagina, string calidad, string leftMargin, string rightMargin, string topMargin, string bottomMargin, bool bCabecera, int bImagenCabecera, string imagenCabecera, bool bJS, bool bActiveX, bool bJpeg, bool bPie, bool bFirma, bool bPaginador, string textoPaginador, int tipoTextoPie, string textoPie, int anchoTextoPie, bool bImagenPie, string imagenPie, int ImagenPieX, int ImagenPieY, string textoLateral, int iPosX, int iPosY, string entorno, int posYnumPagina, int altoCabecera, bool bLineaPie, bool bCabeceraPortada, bool bPiePortada, string portadaPDF)
{
try
{
GestionTraza.Utilidades.escribirLog("WSTOPDF", string.Join(" ", " -- Arranca el proceso de transformación de HTML a PDF"), LogTrazas.DBG, LogCapas.CN, 34);                
bool orientacion = (orientacionPagina == "V" ? false : true);
var fichero = GenerarPdf(htmlString, imagenCabecera, altoCabecera, orientacionPagina, anchoPagina, leftMargin, rightMargin, topMargin, bottomMargin, textoPie);
fichero.Wait();
return fichero.Result;
} catch (Exception e)
{
GestionTraza.Utilidades.escribirLogError(e, "WSTOPDF", "HtmlToPdf", "HtmlToPdf", (int)LogTrazas.ERR, (int)LogCapas.CN, 34);
throw e;
}

}
private async Task<string> GenerarPdf(string htmlString, string imagenCabecera, int altoCabecera, string orientacionPagina, int anchoPagina, string leftMargin, string rightMargin, string topMargin, string bottomMargin, string textoPie) {
string outputFile = "";
try
{
bool orientacion = (orientacionPagina == "V" ? false : true);                
Console.WriteLine("Downloading chromium");
await new BrowserFetcher().DownloadAsync(BrowserFetcher.DefaultChromiumRevision);
Console.WriteLine("Navigating google");
var browser = await Puppeteer.LaunchAsync(new LaunchOptions
{
Headless = true
});
var page = await browser.NewPageAsync();
await page.GoToAsync(htmlString);
await page.PdfAsync(outputFile, new PdfOptions
{
HeaderTemplate = imagenCabecera,
Height = altoCabecera,
Landscape = orientacion,
//OmitBackground = false,
//PageRanges =,
//PreferCSSPageSize = ,
//PrintBackground =,
//Scale =,
Width = anchoPagina,
Format = PaperFormat.A4,
DisplayHeaderFooter = true,
MarginOptions = new MarginOptions
{
Top = topMargin,
Right = rightMargin,
Bottom = bottomMargin,
Left = leftMargin
},
//FooterTemplate = "<div id="footer-template" style="font-size:10px !important; color:#808080; padding-left:10px">Footer Text</div>"
FooterTemplate = textoPie
});
return outputFile;
}
catch (Exception e)
{
GestionTraza.Utilidades.escribirLogError(e, "WSTOPDF", "GenerarPdf", "GenerarPdf", (int)LogTrazas.ERR, (int)LogCapas.CN, 34);
throw e;
}            
}
}
}

你可能需要考虑升级你的web框架。微软从2006年开始建议人们远离ASMX,并正式宣布ASMX为"遗留技术"。在2009年。现在是2023年;ASMX已经死了(或者"维护中",如果你愿意的话)将近15年了。

但是,假设你不能升级到一个现代的框架,有一种方法可以让它工作。

首先,必须以。net Framework 4.5(或更高)为目标,httpRuntime@targetFramework设置为4.5(或更高)。如果你还在。net Framework 4.0(即Windows XP)上,那么就停止吧:你根本不能使用asyncawait

(在ASP. js中)。网项目).一旦您的目标是4.5或更高(并将targetFramework设置为4.5或更高),那么您可以使用异步WebRequest方法。不幸的是,ASMX是一种遗留技术,它不理解或支持async/await。您可以在自己的方法中使用async/await,但不能在任何标记为WebRequest的方法中使用。相反,您需要使用TAP方法并将它们作为APM方法提供给ASMX。像这样:

[WebMethod]
public IAsyncResult BeginHtmlToPdf(string htmlString, string baseURL, int anchoPagina, string tamanoPagina, string orientacionPagina, string calidad, string leftMargin, string rightMargin, string topMargin, string bottomMargin, bool bCabecera, int bImagenCabecera, string imagenCabecera, bool bJS, bool bActiveX, bool bJpeg, bool bPie, bool bFirma, bool bPaginador, string textoPaginador, int tipoTextoPie, string textoPie, int anchoTextoPie, bool bImagenPie, string imagenPie, int ImagenPieX, int ImagenPieY, string textoLateral, int iPosX, int iPosY, string entorno, int posYnumPagina, int altoCabecera, bool bLineaPie, bool bCabeceraPortada, bool bPiePortada, string portadaPDF, AsyncCallback callback, object state)
{
var tcs = new TaskCompletionSource<string>(state);
var task = HtmlToPdfAsync(htmlString, baseURL, ...);
task.ContinueWith(t =>
{
if (t.IsFaulted)
tcs.TrySetException(t.Exception.InnerExceptions);
else if (t.IsCanceled)
tcs.TrySetCanceled();
else
tcs.TrySetResult(t.Result);
if (callback != null)
callback(tcs.Task);
});
return tcs.Task;
}
[WebMethod]
public string EndHtmlToPdf(IAsyncResult result)
{
return ((Task<string>)result).GetAwaiter().GetResult();
}
private async Task<string> HtmlToPdfAsync(string htmlString, string baseURL, int anchoPagina, string tamanoPagina, string orientacionPagina, string calidad, string leftMargin, string rightMargin, string topMargin, string bottomMargin, bool bCabecera, int bImagenCabecera, string imagenCabecera, bool bJS, bool bActiveX, bool bJpeg, bool bPie, bool bFirma, bool bPaginador, string textoPaginador, int tipoTextoPie, string textoPie, int anchoTextoPie, bool bImagenPie, string imagenPie, int ImagenPieX, int ImagenPieY, string textoLateral, int iPosX, int iPosY, string entorno, int posYnumPagina, int altoCabecera, bool bLineaPie, bool bCabeceraPortada, bool bPiePortada, string portadaPDF)
{
try
{
GestionTraza.Utilidades.escribirLog("WSTOPDF", string.Join(" ", " -- Arranca el proceso de transformación de HTML a PDF"), LogTrazas.DBG, LogCapas.CN, 34);                
bool orientacion = (orientacionPagina == "V" ? false : true);
return await GenerarPdf(htmlString, imagenCabecera, altoCabecera, orientacionPagina, anchoPagina, leftMargin, rightMargin, topMargin, bottomMargin, textoPie);
}
catch (Exception e)
{
GestionTraza.Utilidades.escribirLogError(e, "WSTOPDF", "HtmlToPdf", "HtmlToPdf", (int)LogTrazas.ERR, (int)LogCapas.CN, 34);
throw e;
}
}

我不完全确定它是否适用于你的情况,因为你有大量的参数,但值得一试。

最新更新