我有一个聊天机器人正在实现翻译中间件。中间件检测输入的语言并将查询翻译成英语。我一直在努力将检测到的语言另存为变量,以将响应转换为用户的语言,但是遇到了障碍。
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"}]}]
我的问题是我们如何调整该实现以使其与数组外部的detectedLanguage对象一起使用,或者如何调整将其包含在字符串中以与该实现一起使用?
答案 0 :(得分:0)
您的类结构与您的json不匹配。您想要的是以下内容:
internal class DetectedLanguage
{
[JsonProperty("language")]
public string Language { get; set; }
[JsonProperty("score")]
public double Score { get; set; }
}
internal class TranslatorResult
{
[JsonProperty("text")]
public string Text { get; set; }
[JsonProperty("to")]
public string To { get; set; }
}
internal class TranslatorResponse
{
[JsonProperty("detectedLanguage")]
public DetectedLanguage DetectedLanguage { get; set; }
[JsonProperty("translations")]
public IEnumerable<TranslatorResult> Translations { get; set; }
}
请注意,DetectedLanguage
应该如何表示为TranslatorResponse
对象上的单个对象,而您目前还没有这样做。另外,Language
的{{1}}属性也是单个属性,而不是集合。