Прикрутить API Yandex словаря в мой готовый переводчик
Нужно написать переводчик для курсача(1 курс). 2 дня пытаюсь прикрутить и выходит или 400 bad request или она просто копирует вводимый текст. Исправьте, если не сложно. Пытаюсь прикрутить api словаря к api переводчика: //Form1.cs
using System;
using System.Diagnostics;
using System.Windows.Forms;
using Newtonsoft.Json;
namespace Translator
{
public partial class Form1 : Form
{
YandexDictionary dictionary;
YandexTranslator yt;
public Form1()
{
InitializeComponent();
yt = new YandexTranslator();
dictionary = new YandexDictionary();
}
private void LinkLabel1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
{
linkLabel1.LinkVisited = true;
// Navigate to a URL.
Process.Start("http://translate.yandex.ru");
}
private void ИнфоToolStripMenuItem_Click(object sender, EventArgs e)
{
}
private void Button1_Click(object sender, EventArgs e)
{
// Переводчик
string entering_text = "";
string lang ="en-ru";
yt = new YandexTranslator();
en_ru_label.Text = "Русский язык";
ru_en_label.Text = "Английский язык";
outputTextBox.Text = yt.Translate(inputTextBox.Text, lang);
/* //словарь
dictionary = new YandexDictionary();
dict_out_text.Text = dictionary.Dictionary(outputTextBox.Text, entering_text);
*/
}
private void Button2_Click(object sender, EventArgs e)
{
string entering_text = "";
// переводчик
string lang = "ru-en";
yt = new YandexTranslator();
ru_en_label.Text = "Русский язык";
en_ru_label.Text = "Английский язык";
outputTextBox.Text = yt.Translate(inputTextBox.Text, lang);
/*
//словарь
dict_out_text.Text = dictionary.Dictionary(outputTextBox.Text,entering_text);
*/
}
private void MenuStrip1_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
{
}
private void ToolStripMenuItem1_Click(object sender, EventArgs e)
{
MessageBox.Show("Программа создана для облегчения перевода между людьми, говорящими на " +
" разных языках");
}
private void outputTextBox_TextChanged(object sender, EventArgs e)
{
// string lang = "ru-en";
dictionary = new YandexDictionary();
string lang = "ru-en";
/* //Словарь
dict_out_text.Text = dictionary.Dictionary(inputTextBox.Text,lang);
*/
}
}
}
// YandexTranslator.cs
using System.IO;
using System.Net;
using Newtonsoft.Json;
namespace Translator
{
class YandexTranslator
{
public string Translate(string input_text, string lang)
{
if (input_text.Length == 0)
return "Ошибка запроса. Текст не обнаружен! ";
else
{
WebRequest request = WebRequest.Create("https://translate.yandex.net/api/v1.5/tr.json/translate?"
+ "key=trnsl.1.1.20200226T182352Z.f50284e5823499f7.dafb6352b04e04f4d4f6d95e7d4d076fa972c2ed"
+ "&text=" + input_text
+ "&lang=" + lang);
WebResponse response = request.GetResponse();
using (StreamReader stream = new StreamReader(response.GetResponseStream()))
{
string line;
if ((line = stream.ReadLine()) != null)
{
Translation translation = JsonConvert.DeserializeObject<Translation>(line);
input_text = "";
foreach (string result_of_working in translation.Text)
{
input_text += result_of_working;
}
}
}
return input_text;
}
}
}
class Translation
{
public string Code { get; set; }
public string Lang { get; set; }
public string[] Text { get; set; }
}
}
//YandexDictionary.cs
using System.IO;
using System.Net;
using Newtonsoft.Json;
namespace Translator
{
class YandexDictionary
{
public string Dictionary(string entering_text, string lang)
{
if (entering_text.Length == 0)
return "Error";
else
{
WebRequest request = WebRequest.Create("https://dictionary.yandex.net/api/v1/dicservice.json/lookup?"
+ "key=dict.1.1.20200226T180945Z.3dff57d76cbaf934.a871b8b923f38ae1cd61bd5139c51ab39f217f83"
+ "&lang=" + lang
+ "&text=" + entering_text);
WebResponse response = request.GetResponse();
using (StreamReader reader = new StreamReader(response.GetResponseStream()))
{
string added_string;
if ((added_string = reader.ReadLine()) == null)
{
Check_Dictionary dict_yandex = JsonConvert.DeserializeObject<Check_Dictionary>(added_string);
entering_text = "";
foreach (string dict_result in dict_yandex.Text)
{
entering_text += dict_result;
}
}
}
return entering_text;
}
}
}
class Check_Dictionary
{
public string Code { get; set; }
public string Lang { get; set; }
public string[] Text { get; set; }
}
}
Ответы (1 шт):
1) Создадим два пустых класса YandexAnswer и YandexServices.
2) Создадим тестовый проект и напишем пару тестов
[TestClass()]
public class YandexServicesTests
{
[TestMethod()]
public async Task GetTranslateAnswerAsyncTest()
{
var ru = "семь раз отмерь один раз отрежь";
var eng = "measure twice cut once\r\n";
YandexServices sut = new YandexServices();
YandexServices.TranslationDirection direction
= YandexServices.TranslationDirection.RuEng;
YandexAnswer answer = await sut.GetTranslateAnswerAsync(ru, direction);
Assert.AreEqual("OK", answer.Code);
Assert.AreEqual(eng, answer.Text);
}
[TestMethod()]
public async Task GetDictionaryAnswerAsyncTest()
{
var ru = "мысль";
var eng = "thought";
YandexServices sut = new YandexServices();
YandexServices.TranslationDirection direction
= YandexServices.TranslationDirection.RuEng;
YandexAnswer answer = await sut.GetDictionaryAnswerAsync(ru, direction);
Assert.AreEqual("OK", answer.Code);
Assert.IsTrue(answer.Text.Contains(eng));
}
}
3) Поработаем немного над тем, чтоб эти тесты стали зелеными и получим в итоге такие классы
public class YandexAnswer
{
private Dictionary _dictionaryAnswer;
private Translator _translatorAnswer;
public string Code { get; set; }
public string Lang { get; set; }
public string Text { get; set; }
public Dictionary DictionaryAnswer
{
get => _dictionaryAnswer;
set
{
_dictionaryAnswer = value;
if (_dictionaryAnswer != null)
{
SetTextFromDictionaryAnswer();
}
}
}
public Translator TranslatorAnswer
{
get => _translatorAnswer;
set
{
_translatorAnswer = value;
if (_translatorAnswer != null)
{
SetTextFromTranslatorAnswer();
}
}
}
private void SetTextFromTranslatorAnswer()
{
var sb = new StringBuilder();
_translatorAnswer.text?.ForEach(t => sb.AppendLine(t));
Text = sb.ToString();
}
private void SetTextFromDictionaryAnswer()
{
if (_dictionaryAnswer.def == null)
{
return;
}
var sb = new StringBuilder();
foreach (var def in _dictionaryAnswer.def)
{
int counter = 0;
foreach (var tr in def.tr)
{
sb.AppendLine($"{++counter}) {tr.text}");
}
}
Text = sb.ToString();
}
}
public class Translator
{
public int code { get; set; }
public string lang { get; set; }
public List<string> text { get; set; }
}
public class Dictionary
{
public Head head { get; set; }
public Def[] def { get; set; }
}
public class Head
{
}
public class Def
{
public string text { get; set; }
public string pos { get; set; }
public string gen { get; set; }
public string anm { get; set; }
public Tr[] tr { get; set; }
}
public class Tr
{
public string text { get; set; }
public string pos { get; set; }
public Syn[] syn { get; set; }
public Mean[] mean { get; set; }
public Ex[] ex { get; set; }
}
public class Syn
{
public string text { get; set; }
public string pos { get; set; }
}
public class Mean
{
public string text { get; set; }
}
public class Ex
{
public string text { get; set; }
public Tr1[] tr { get; set; }
}
public class Tr1
{
public string text { get; set; }
}
и
public class YandexServices
{
private const string _addressTranslator = "https://translate.yandex.net/api/v1.5/tr.json/translate?" +
"key=trnsl.1.1.20200226T182352Z.f50284e5823499f7.dafb6352b04e04f4d4f6d95e7d4d076fa972c2ed";
private const string _addressDictionary = "https://dictionary.yandex.net/api/v1/dicservice.json/lookup?" +
"key=dict.1.1.20200226T180945Z.3dff57d76cbaf934.a871b8b923f38ae1cd61bd5139c51ab39f217f83";
private readonly HttpClient _httpClient;
public enum TranslationDirection { RuEng, EngRu }
public YandexServices()
{
_httpClient = new HttpClient();
_httpClient.Timeout = new TimeSpan(0, 0, 30);
}
public async Task<YandexAnswer> GetTranslateAnswerAsync(string text, TranslationDirection direction)
{
var answer = new YandexAnswer
{
Lang = GetLang(direction),
TranslatorAnswer = new Translator()
};
if (String.IsNullOrWhiteSpace(text))
{
answer.Text = "Нет текста для перевода";
return answer;
}
var address = String.Concat(_addressTranslator,
"&lang=", answer.Lang, "&text=", text);
answer = await GetAnswerAsync(address, answer);
return answer;
}
public async Task<YandexAnswer> GetDictionaryAnswerAsync(string text, TranslationDirection direction)
{
var answer = new YandexAnswer
{
Lang = GetLang(direction),
DictionaryAnswer = new Dictionary()
};
if (String.IsNullOrWhiteSpace(text))
{
answer.Text = "Нет слова(ов) для перевода";
return answer;
}
var address = String.Concat(_addressDictionary,
"&lang=", answer.Lang, "&text=", text);
answer = await GetAnswerAsync(address, answer);
return answer;
}
private string GetLang(TranslationDirection direction)
{
switch (direction)
{
case TranslationDirection.RuEng:
return "ru-en";
case TranslationDirection.EngRu:
return "en-ru";
default:
throw new ArgumentException(nameof(direction));
}
}
private async Task<YandexAnswer> GetAnswerAsync(string address, YandexAnswer answer)
{
var response = await _httpClient.GetAsync(address);
if (response.IsSuccessStatusCode)
{
var json = await response.Content.ReadAsStringAsync();
if (answer.DictionaryAnswer != null)
{
answer.DictionaryAnswer = JsonConvert.DeserializeObject<Dictionary>(json);
}
else
{
answer.TranslatorAnswer = JsonConvert.DeserializeObject<Translator>(json);
}
}
else
{
answer.Text = "Ошибка доступа к сервису Яндекса";
}
answer.Code = response.StatusCode.ToString();
return answer;
}
}
4) Создадим пустой класс MainViewModel и напишем к нему такие тесты
[TestClass()]
public class MainViewModelTests
{
[TestMethod()]
public async Task GetTransationAsync_WhenRusInput_ThenEngOutput()
{
string input = "семь раз отмерь один раз отрежь";
string output = "measure twice cut once\r\n";
YandexServices services = new YandexServices();
MainViewModel sut = new MainViewModel(services);
sut.Input = input;
sut.SelectedLang = 0;
await sut.GetTransationAsync();
Assert.AreEqual(output, sut.Output);
}
[TestMethod()]
public async Task GetTransationAsync_WhenEngInput_ThenRusOutput()
{
string input = "measure twice cut once";
string output = "семь раз отмерь один раз отрежь";
YandexServices services = new YandexServices();
MainViewModel sut = new MainViewModel(services);
sut.Input = input;
sut.SelectedLang = 1;
await sut.GetTransationAsync();
Assert.IsTrue(sut.Output.Contains(output));
}
[TestMethod()]
public async Task GetDictionaryAsync_WhenRusInput_ThenEngOutput()
{
string input = "мысль";
string output = "thought";
YandexServices services = new YandexServices();
MainViewModel sut = new MainViewModel(services);
sut.Input = input;
sut.SelectedLang = 0;
await sut.GetDictionaryAsync();
Assert.IsTrue(sut.Output.Contains(output));
}
[TestMethod()]
public async Task GetDictionaryAsync_WhenEngInput_ThenRusOutput()
{
string input = "thought";
string output = "мысль";
YandexServices services = new YandexServices();
MainViewModel sut = new MainViewModel(services);
sut.Input = input;
sut.SelectedLang = 1;
await sut.GetDictionaryAsync();
Assert.IsTrue(sut.Output.Contains(output));
}
}
5) После прохождения тестов получим такой класс
public class MainViewModel
{
private YandexServices _yandexServices;
public MainViewModel(YandexServices yandexServices)
{
_yandexServices = yandexServices ??
throw new ArgumentNullException(nameof(yandexServices));
Langs = new List<string>() { "с русского на английский", "с английского на русский" };
}
public event EventHandler OutputChanged;
private string _Output;
public string Output
{
get { return _Output; }
set
{
_Output = value;
OutputChanged?.Invoke(this, EventArgs.Empty);
}
}
public string Input { get; set; }
public List<string> Langs { get; }
public int SelectedLang { get; set; }
public async Task GetTransationAsync()
{
var direction = GetDirection();
var result = await _yandexServices
.GetTranslateAnswerAsync(Input, direction);
Output = result.Text;
}
public async Task GetDictionaryAsync()
{
var direction = GetDirection();
var result = await _yandexServices
.GetDictionaryAnswerAsync(Input, direction);
Output = result.Text;
}
private YandexServices.TranslationDirection GetDirection()
{
if (SelectedLang == 0)
{
return YandexServices.TranslationDirection.RuEng;
}
else
{
return YandexServices.TranslationDirection.EngRu;
}
}
}
6) Набросаем на форму контролы и напишем привязки к нашей вьюмодели
public partial class FormMain : Form
{
private readonly MainViewModel _viewModel;
public FormMain()
{
InitializeComponent();
_viewModel = new MainViewModel(new YandexServices());
//привязки
_textBoxInput.DataBindings.Add("Text", _viewModel, nameof(_viewModel.Input));
_textBoxOutput.DataBindings.Add("Text", _viewModel, nameof(_viewModel.Output));
_viewModel.OutputChanged += (s, e) => _textBoxOutput.DataBindings[0].ReadValue();
_comboBoxLang.DataSource = _viewModel.Langs;
_comboBoxLang.DataBindings.Add("SelectedIndex", _viewModel, nameof(_viewModel.SelectedLang));
//кнопки
_buttonTrans.Click += async (s, e) => await _viewModel.GetTransationAsync();
_buttonDict.Click += async (s, e) => await _viewModel.GetDictionaryAsync();
}
}
Теперь можно запустить и проверить работу программы

Пример целиком здесь