RecognitionResult is null despite success status and a valid HTTP response
I’m using the .NET Cognitive Services SDK. The client is the ComputerVisionClient
and I’m getting text via the Read API.
[Fact] public async Task BenAndJerryRead() { var client = new ComputerVisionClient(new ApiKeyServiceClientCredentials(Configuration.SubscriptionKey)) { Endpoint = Configuration.Endpoint }; var testImage = new FileInfo(@"Images\COVID Warning.jpg"); Assert.True(testImage.Exists); BatchReadFileInStreamHeaders submission; await using (var fileStream = testImage.OpenRead()) { submission = await client.BatchReadFileInStreamAsync(fileStream, CancellationToken.None); } var operationLocation = submission.OperationLocation; var submissionId = operationLocation.Substring(operationLocation.Length - 36); Assert.NotNull(submissionId); Assert.NotEmpty(submissionId); TextOperationResult result; do { result = await client.GetTextOperationResultAsync(submissionId, CancellationToken.None); _testOutputHelper.WriteLine($"Polling: {result.Status}"); await Task.Delay(100); } while (result.Status != Succeeded && result.Status != Failed); Assert.Equal(Succeeded, result.Status); Assert.NotNull(result.RecognitionResult); }
I’m calling the Cognitive Services Read API. I get the initial operationLocation
and poll it for a success status which is returned as expected. However the RecognitionResult
property of the TextOperationResult.RecognitionResult
is null
. The Fiddler trace below shows that the response is valid and has data.
GET https://ugc.cognitiveservices.azure.com//vision/v2.0/textOperations/b7d275e3-1f1c-408f-9846-f19f3cad9004 HTTP/1.1 Host: HIDDEN.cognitiveservices.azure.com Ocp-Apim-Subscription-Key: HIDDEN User-Agent: FxVersion/4.700.20.20201 OSName/Windows OSVersion/Microsoft.Windows.10.0.18363 Microsoft.Azure.CognitiveServices.Vision.ComputerVision.ComputerVisionClient/5.0.19.28102
HTTP/1.1 200 OK Cache-Control: no-cache Pragma: no-cache Content-Length: 2432 Content-Type: application/json; charset=utf-8 Expires: -1 X-AspNet-Version: 4.0.30319 X-Powered-By: ASP.NET CSP-Billing-Usage: CognitiveServices.ComputerVision.Transaction=1 apim-request-id: a77adf8b-8012-4a66-ad63-97319a305f3b Strict-Transport-Security: max-age=31536000; includeSubDomains; preload x-content-type-options: nosniff Date: Sun, 05 Jul 2020 14:13:59 GMT {"status":"Succeeded","recognitionResults":[{"page":1,"clockwiseOrientation":359.81,"width":410,"height":230,"unit":"pixel","lines":[{"boundingBox":[20,22,383,21,384,47,21,48],"text":"GOV.UK CORONAVIRUS ALERT","words":[{"boundingBox":[22,23,113,23,113,48,24,48],"text":"GOV.UK"},{"boundingBox":[121,23,303,22,303,48,122,48],"text":"CORONAVIRUS"},{"boundingBox":[308,22,384,22,383,47,308,48],"text":"ALERT"}]},{"boundingBox":[22,53,341,55,340,80,21,78],"text":"New rules in force now: you","words":[{"boundingBox":[22,56,69,55,68,78,22,78],"text":"New"},{"boundingBox":[79,55,139,55,138,79,78,79],"text":"rules"},{"boundingBox":[143,55,163,55,163,79,142,79],"text":"in"},{"boundingBox":[171,55,230,56,230,80,170,79],"text":"force"},{"boundingBox":[236,56,295,57,294,80,235,80],"text":"now:"},{"boundingBox":[299,57,340,58,339,80,298,80],"text":"you"}]},{"boundingBox":[21,86,379,82,380,109,22,113],"text":"must stay at home. More info &","words":[{"boundingBox":[22,86,81,86,81,113,22,113],"text":"must"},{"boundingBox":[86,86,137,86,137,112,87,113],"text":"stay"},{"boundingBox":[142,86,163,86,164,112,142,112],"text":"at"},{"boundingBox":[169,86,242,85,242,111,169,112],"text":"home."},{"boundingBox":[248,85,308,84,309,110,248,111],"text":"More"},{"boundingBox":[314,84,362,83,362,109,314,110],"text":"info"},{"boundingBox":[368,83,380,83,380,109,368,109],"text":"&"}]},{"boundingBox":[20,115,275,114,276,142,21,143],"text":"exemptions at gov.uk/","words":[{"boundingBox":[23,118,158,115,158,144,23,141],"text":"exemptions"},{"boundingBox":[162,115,186,115,186,143,162,144],"text":"at"},{"boundingBox":[191,115,274,116,275,142,191,143],"text":"gov.uk/"}]},{"boundingBox":[20,146,322,145,323,171,21,172],"text":"coronavirus Stay at home.","words":[{"boundingBox":[22,149,158,146,158,173,22,170],"text":"coronavirus"},{"boundingBox":[165,146,215,146,214,173,165,173],"text":"Stay"},{"boundingBox":[222,146,246,146,245,172,221,173],"text":"at"},{"boundingBox":[250,146,323,147,322,170,249,172],"text":"home."}]},{"boundingBox":[20,175,343,174,344,200,21,201],"text":"Protect the NHS. Save lives.","words":[{"boundingBox":[22,178,109,176,109,201,22,200],"text":"Protect"},{"boundingBox":[113,176,151,176,151,201,113,201],"text":"the"},{"boundingBox":[156,176,221,175,221,201,156,201],"text":"NHS."},{"boundingBox":[226,175,280,175,281,201,226,201],"text":"Save"},{"boundingBox":[286,175,344,176,344,200,286,201],"text":"lives."}]}]}]}
Why isn’t the JSON being deserialized into the result?
The reason is the name of the properties are not same with the attributes in TextOperationResult
class, so it can not deserialize to json by the name of properties.
We can see the two attributes(Status
and RecognitionResult
) in code of TextOperationResult
class.
The code [JsonProperty(PropertyName = "status")]
is used to correspond Stauts
to status
, so you can get result.Status
success.
The code [JsonProperty(PropertyName = "recognitionResult")]
is used to correspond RecognitionResult
to recognitionResult
, but the property in your result data is recognitionResults
, so your code result.RecognitionResult
can’t get data success, it will just return you with null value.
Hope it helps~
You might have used the wrong pair of APIs and got the wrong result accordingly.
Please replace GetTextOperationResultAsync() with GetReadOperationResultAsync()
Refer to the sample code of BatchReadFile:
- invoke BatchReadFileInStreamAsync() to post the request
- invoke GetReadOperationResultAsync() to get the result
Here’s another example you may be interested in RecognizeText:
- invoke RecognizeTextInStreamAsync() to post the request
- invoke GetTextOperationResultAsync() to get the result