【发布时间】:2020-10-30 22:01:02
【问题描述】:
我有一个正在实现翻译中间件的聊天机器人。中间件检测传入的语言并将查询翻译成英语。我一直在努力将检测到的语言保存为一个变量,以便将响应翻译成用户的语言,但遇到了障碍。
protected override async Task OnMessageActivityAsync(ITurnContext<IMessageActivity> turnContext, CancellationToken cancellationToken)
{
var body = new object[] { new { Text = turnContext.Activity.Text } };
var requestBody = JsonConvert.SerializeObject(body);
//Console.WriteLine("------------------------------------------------------------------------");
//Console.WriteLine(requestBody);
//Console.WriteLine("------------------------------------------------------------------------");
//var languageChoice = "de";
using (var client = new HttpClient())
using (var request = new HttpRequestMessage())
{
//var uri = "https://api.cognitive.microsofttranslator.com" + "/translate?api-version=3.0" + "&from=" + languageChoice + "&to=" + "en";
var uri = "https://api.cognitive.microsofttranslator.com" + "/translate?api-version=3.0" + "&to=" + "en";
request.Method = HttpMethod.Post;
request.RequestUri = new Uri(uri);
request.Content = new StringContent(requestBody, Encoding.UTF8, "application/json");
request.Headers.Add("Ocp-Apim-Subscription-Key", _configuration["TranslatorKey"]);
request.Headers.Add("Ocp-Apim-Subscription-Region", "westus2");
var translatedResponse = await client.SendAsync(request);
var responseBody = await translatedResponse.Content.ReadAsStringAsync();
Console.WriteLine("------------------------------------------------------------------------");
Console.WriteLine(responseBody);
Console.WriteLine("------------------------------------------------------------------------");
var translation = JsonConvert.DeserializeObject<TranslatorResponse[]>(responseBody);
var detectedLanguage = JsonConvert.DeserializeObject<DetectLanguage[]>(responseBody);
var ourResponse = detectedLanguage?.FirstOrDefault()?.DetectedLanguage?.FirstOrDefault()?.Language.ToString();
Console.WriteLine("------------------------------------------------------------------------");
Console.WriteLine(ourResponse);
Console.WriteLine("------------------------------------------------------------------------");
//Console.WriteLine("------------------------------------------------------------------------");
//Console.WriteLine(turnContext.Activity.Text);
//Console.WriteLine(translation?.FirstOrDefault()?.Translations?.FirstOrDefault()?.Text.ToString());
//Console.WriteLine("------------------------------------------------------------------------");
// Update the translation field
turnContext.Activity.Text = translation?.FirstOrDefault()?.Translations?.FirstOrDefault()?.Text.ToString();
}
// First, we use the dispatch model to determine which cognitive service (LUIS or QnA) to use.
var recognizerResult = await _botServices.Dispatch.RecognizeAsync(turnContext, cancellationToken);
// Top intent tell us which cognitive service to use.
var topIntent = recognizerResult.GetTopScoringIntent();
// Next, we call the dispatcher with the top intent.
// ***** ERROR *****
await DispatchToTopIntentAsync(turnContext, topIntent.intent, recognizerResult, cancellationToken);
}
使用来自 responseBody 的控制台日志:
[{"detectedLanguage":{"language":"es","score":1.0},"translations":[{"text":"Hello","to":"en"}]}]
我们已经确定 responseBody 是一个 Object 数组,其中包含一个属性“detectedLanguage”,一个对象,具有属性“language”和“score”。 为了从对象“detectedLanguage”中检索变量“language”,我们进行了以下尝试,使用作为翻译文本返回的“turnContext.Activity.Text”作为示例。
我们还添加了两个模拟“turnContext.Activity.Text”实现的内部类:
1)
namespace Microsoft.BotBuilderSamples.Translation.Model
{
/// <summary>
/// Array of translated results from Translator API v3.
/// </summary>
internal class TranslatorResponse
{
[JsonProperty("translations")]
public IEnumerable<TranslatorResult> Translations { get; set; }
}
internal class DetectLanguage
{
[JsonProperty("detectedLanguage")]
public IEnumerable<LanguageResult> DetectedLanguage { get; set; }
}
}
using Newtonsoft.Json;
namespace Microsoft.BotBuilderSamples.Translation.Model
{
/// <summary>
/// Translation result from Translator API v3.
/// </summary>
internal class TranslatorResult
{
[JsonProperty("text")]
public string Text { get; set; }
[JsonProperty("to")]
public string To { get; set; }
}
internal class LanguageResult
{
[JsonProperty("language")]
public string Language { get; set; }
}
}
但是,当我们尝试在控制台中测试并显示“ourResponse”时,我们会遇到以下错误消息:
fail: Microsoft.Bot.Builder.Integration.AspNet.Core.BotFrameworkHttpAdapter[0]
[OnTurnError] unhandled error : Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.IEnumerable`1[Microsoft.BotBuilderSamples.Translation.Model.LanguageResult]' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly.
To fix this error either change the JSON to a JSON array (e.g. [1,2,3]) or change the deserialized type so that it is a normal .NET type (e.g. not a primitive type like integer, not a collection type like an array or List<T>) that can be deserialized from a JSON object. JsonObjectAttribute can also be added to the type to force it to deserialize from a JSON object.
Path '[0].detectedLanguage.language', line 1, position 33.
我们已经确定我们遇到了这个错误,因为“detectedLanguage”不是像“translations”那样的数组。 (显示在下面的控制台输出中):
[{"detectedLanguage":{"language":"es","score":1.0},"translations":[{"text":"Hello","to":"en"}]}]
我的问题是我们如何调整此实现以使用数组外的对象检测语言,或者我们如何调整检测语言以包含在字符串中以使用该实现?
【问题讨论】:
标签: c# json chatbot azure-language-understanding language-translation