C# Azure API调用在控制台应用程序中工作;不在MVC中

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方法时,效果很好(文件是用返回的文

我有一个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