C# Azure API调用在控制台应用程序中工作;不在MVC中
我有一个asp.net MVC应用程序,允许用户将PDF/图像上传到系统中。然后,我想将此PDF发送到Azure Read API,并将返回的文本存储在系统上的.text文件中(以便稍后将部分数据输入数据库) 我在控制台应用程序中测试它时,它工作得很好,尽管当我尝试将它实现到我的MVC web应用程序中时,我无法让它工作;当我上传PDF时,文件会被上传,尽管没有其他事情发生,即没有使用返回的数据创建文本文件。当我在控制台应用程序中尝试使用相同的Azure API方法时,效果很好(文件是用返回的文本创建的) 我的控制器:C# Azure API调用在控制台应用程序中工作;不在MVC中,c#,asp.net,asp.net-mvc,azure,azure-cognitive-services,C#,Asp.net,Asp.net Mvc,Azure,Azure Cognitive Services,我有一个asp.net MVC应用程序,允许用户将PDF/图像上传到系统中。然后,我想将此PDF发送到Azure Read API,并将返回的文本存储在系统上的.text文件中(以便稍后将部分数据输入数据库) 我在控制台应用程序中测试它时,它工作得很好,尽管当我尝试将它实现到我的MVC web应用程序中时,我无法让它工作;当我上传PDF时,文件会被上传,尽管没有其他事情发生,即没有使用返回的数据创建文本文件。当我在控制台应用程序中尝试使用相同的Azure API方法时,效果很好(文件是用返回的文
public ActionResult Upload()
{
return View();
}
[HttpPost]
public ActionResult Upload(HttpPostedFileBase file)
{
string filename = Guid.NewGuid() + Path.GetExtension(file.FileName);
string filepath = @"C:\Users\35385\source\repos\BookingSystem\BookingSystem\Surveys\" + filename;
file.SaveAs(Path.Combine(Server.MapPath("/Surveys"), filename));
AzureVisionAPI.ExtractToTextFile(filepath);
return View();
}
public ActionResult Upload()
{
return View();
}
[HttpPost]
public async Task<ActionResult> Upload(HttpPostedFileBase file)
{
string filename = Guid.NewGuid() + Path.GetExtension(file.FileName);
string filepath = @"C:\Users\35385\source\repos\BookingSystem\BookingSystem\Surveys\" + filename;
file.SaveAs(Path.Combine(Server.MapPath("/Surveys"), filename));
await AzureVisionAPI.ExtractToTextFile(filepath);
return View();
}
My Azure API调用帮助程序方法:
namespace BookingSystem.Helpers
{
static class AzureVisionAPI
{
static string subscriptionKey = ("SUBSCRIPTON_KEY");
static string endpoint = ("END_POINT");
public static ComputerVisionClient Authenticate(string endpoint, string key)
{
ComputerVisionClient client =
new ComputerVisionClient(new ApiKeyServiceClientCredentials(key))
{ Endpoint = endpoint };
return client;
}
public static void ExtractToTextFile(string filename)
{
ComputerVisionClient client = Authenticate(endpoint, subscriptionKey);
ExtractTextLocal(client, filename).Wait();
}
public static async Task ExtractTextLocal(ComputerVisionClient client, string localImage)
{
// Helps calucalte starting index to retrieve operation ID
const int numberOfCharsInOperationId = 36;
using (Stream imageStream = File.OpenRead(localImage))
{
// Read the text from the local image
BatchReadFileInStreamHeaders localFileTextHeaders = await client.BatchReadFileInStreamAsync(imageStream);
// Get the operation location (operation ID)
string operationLocation = localFileTextHeaders.OperationLocation;
// Retrieve the URI where the recognized text will be stored from the Operation-Location header.
string operationId = operationLocation.Substring(operationLocation.Length - numberOfCharsInOperationId);
// Extract text, wait for it to complete.
int i = 0;
int maxRetries = 10;
ReadOperationResult results;
do
{
results = await client.GetReadOperationResultAsync(operationId);
await Task.Delay(1000);
if (maxRetries == 9)
{
throw new Exception("Azure API timed out");
}
}
while ((results.Status == TextOperationStatusCodes.Running ||
results.Status == TextOperationStatusCodes.NotStarted) && i++ < maxRetries);
// Display the found text.
var textRecognitionLocalFileResults = results.RecognitionResults;
foreach (TextRecognitionResult recResult in textRecognitionLocalFileResults)
{
using (StreamWriter sw = new StreamWriter(@"C:\Users\35385\source\repos\BookingSystem\BookingSystem\surveytest.txt"))
{
foreach (Line line in recResult.Lines)
{
sw.WriteLine(line.Text);
}
}
}
}
}
}
}
namespace BookingSystem.Helpers
{
静态类AzureVisionAPI
{
静态字符串subscriptionKey=(“SUBSCRIPTON_KEY”);
静态字符串端点=(“端点”);
公共静态计算机VisionClient身份验证(字符串端点、字符串密钥)
{
ComputerVisionClient客户端=
新的ComputerVisionClient(新的ApiKeyServiceClientCredentials(键))
{Endpoint=Endpoint};
返回客户;
}
公共静态void ExtractToTextFile(字符串文件名)
{
ComputerVisionClient客户端=身份验证(端点、订阅密钥);
ExtractTextLocal(客户端,文件名).Wait();
}
公共静态异步任务ExtractTextLocal(ComputerVisionClient客户端,字符串localImage)
{
//帮助calucalte启动索引以检索操作ID
const int numberofcharsinoperation id=36;
使用(Stream-imageStream=File.OpenRead(localImage))
{
//从本地图像中读取文本
BatchReadFileInStreamHeaders localFileTextHeaders=等待客户端。BatchReadFileInStreamAsync(imageStream);
//获取操作位置(操作ID)
string operationLocation=localFileTextHeaders.operationLocation;
//从操作位置标头检索将存储识别文本的URI。
字符串operationId=operationLocation.Substring(operationLocation.Length-numberOfCharsInOperationId);
//提取文本,等待其完成。
int i=0;
int maxRetries=10;
重新操作结果;
做
{
结果=等待客户端.GetReadOperationResultAsync(operationId);
等待任务。延迟(1000);
如果(maxRetries==9)
{
抛出新异常(“Azure API超时”);
}
}
而((results.Status==TextOperationStatusCodes.Running||
results.Status==TextOperationStatusCodes.NotStarted)和&i++
您可能会在这里看到异步死锁。不要使用.Wait()
而是等待从异步方法返回的任务
发生的情况是,在您第一次执行Wait
时,该方法返回到调用.Wait()
的方法,这将阻止线程并独占访问当前的SynchronizationContext
,当内部等待操作完成时,以下代码将在同一SynchronizationContext
上排队,它被阻塞了。.Wait()
将永远不会停止阻塞,因为任务
永远无法完成。这称为异步死锁
这里最好的处理方法是使控制器异步并返回任务
,然后自上而下使用async/wait。处理此问题的另一种方法是将.ConfigureAwait(false)
分散到所有任务中
您的等待
,但是处理异步工作时最好不要阻塞
您的代码可能如下所示:
控制器:
public ActionResult Upload()
{
return View();
}
[HttpPost]
public ActionResult Upload(HttpPostedFileBase file)
{
string filename = Guid.NewGuid() + Path.GetExtension(file.FileName);
string filepath = @"C:\Users\35385\source\repos\BookingSystem\BookingSystem\Surveys\" + filename;
file.SaveAs(Path.Combine(Server.MapPath("/Surveys"), filename));
AzureVisionAPI.ExtractToTextFile(filepath);
return View();
}
public ActionResult Upload()
{
return View();
}
[HttpPost]
public async Task<ActionResult> Upload(HttpPostedFileBase file)
{
string filename = Guid.NewGuid() + Path.GetExtension(file.FileName);
string filepath = @"C:\Users\35385\source\repos\BookingSystem\BookingSystem\Surveys\" + filename;
file.SaveAs(Path.Combine(Server.MapPath("/Surveys"), filename));
await AzureVisionAPI.ExtractToTextFile(filepath);
return View();
}
public ActionResult上传()
{
返回视图();
}
[HttpPost]
公共异步任务上载(HttpPostedFileBase文件)
{
字符串文件名=Guid.NewGuid()+Path.GetExtension(file.filename);
字符串文件路径=@“C:\Users\35385\source\repos\BookingSystem\BookingSystem\Surveys\”+文件名;
file.SaveAs(Path.Combine(Server.MapPath(“/Surveys”),filename));
等待AzureVisionAPI.ExtractToTextFile(文件路径);
返回视图();
}
AzureVisionAPI:
namespace BookingSystem.Helpers
{
static class AzureVisionAPI
{
static string subscriptionKey = ("SUBSCRIPTON_KEY");
static string endpoint = ("END_POINT");
public static ComputerVisionClient Authenticate(string endpoint, string key)
{
ComputerVisionClient client =
new ComputerVisionClient(new ApiKeyServiceClientCredentials(key))
{ Endpoint = endpoint };
return client;
}
public static async Task ExtractToTextFile(string filename)
{
ComputerVisionClient client = Authenticate(endpoint, subscriptionKey);
await ExtractTextLocal(client, filename);
}
public static async Task ExtractTextLocal(ComputerVisionClient client, string localImage)
{
// Helps calucalte starting index to retrieve operation ID
const int numberOfCharsInOperationId = 36;
using (Stream imageStream = File.OpenRead(localImage))
{
// Read the text from the local image
BatchReadFileInStreamHeaders localFileTextHeaders = await client.BatchReadFileInStreamAsync(imageStream);
// Get the operation location (operation ID)
string operationLocation = localFileTextHeaders.OperationLocation;
// Retrieve the URI where the recognized text will be stored from the Operation-Location header.
string operationId = operationLocation.Substring(operationLocation.Length - numberOfCharsInOperationId);
// Extract text, wait for it to complete.
int i = 0;
int maxRetries = 10;
ReadOperationResult results;
do
{
results = await client.GetReadOperationResultAsync(operationId);
await Task.Delay(1000);
if (maxRetries == 9)
{
throw new Exception("Azure API timed out");
}
}
while ((results.Status == TextOperationStatusCodes.Running ||
results.Status == TextOperationStatusCodes.NotStarted) && i++ < maxRetries);
// Display the found text.
var textRecognitionLocalFileResults = results.RecognitionResults;
foreach (TextRecognitionResult recResult in textRecognitionLocalFileResults)
{
using (StreamWriter sw = new StreamWriter(@"C:\Users\35385\source\repos\BookingSystem\BookingSystem\surveytest.txt"))
{
foreach (Line line in recResult.Lines)
{
sw.WriteLine(line.Text);
}
}
}
}
}
}
}
namespace BookingSystem.Helpers
{
静态类AzureVisionAPI
{
静态字符串subscriptionKey=(“SUBSCRIPTON_KEY”);
静态字符串端点=(“端点”);
公共静态计算机VisionClient身份验证(字符串端点、字符串密钥)
{
ComputerVisionClient客户端=
新的ComputerVisionClient(新的ApiKeyServiceClientCredentials(键))
{Endpoint=Endpoint};
返回客户;
}
公共静态异步任务ExtractToTextFile(字符串文件名)
{
ComputerVisionClient客户端=身份验证(端点,subscr