Ответы пользователя по тегу C#
  • Как создавать несколько объектов класса в цикле?

    Casper-SC
    @Casper-SC
    Программист (.NET)
    Program.cs
    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Text;
    using System.Text.Encodings.Web;
    using System.Text.Json;
    using System.Text.Unicode;
    
    namespace ConsoleApp
    {
        class Program
        {
            static void Main(string[] args)
            {
                // Чтение JSON из файла и десериализация.
                string pathToFile = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "PartnerData.json");
                string jsonText = File.ReadAllText(pathToFile, Encoding.UTF8);
                var parterAddressesFromFile = JsonSerializer.Deserialize<TriggerData>(jsonText);
    
                // Вывод на консоль.
                Display(parterAddressesFromFile);
    
                // Создание нового экземпляра класса TriggerData и его заполнение данными.
                var data = new TriggerData()
                {
                    PartnerAddresses = new List<PartnerAddress>()
                    {
                        new PartnerAddress()
                        {
                            Type = "Тип 0001",
                            Country = "Страна 0001",
                            Region = "Регион 0001",
                            City = "Город 0001",
                            Presentation = "Представление 0001",
                        },
                        new PartnerAddress()
                        {
                            Type = "Тип 0002",
                            Country = "Страна 0002",
                            Region = "Регион 00021",
                            City = "Город 0002",
                            Presentation = "Представление 0002",
                        }
                    }
                };
    
                // Сериализация.
                var options = new JsonSerializerOptions
                {
                    Encoder = JavaScriptEncoder.Create(UnicodeRanges.BasicLatin, UnicodeRanges.Cyrillic),
                    WriteIndented = true,
                };
                var newJsonText = JsonSerializer.Serialize(data, options);
    
                // Вывод на консоль.
                Console.WriteLine(newJsonText);
            }
    
            private static void Display(TriggerData data)
            {
                // Способ 1.
                foreach (var address in data.PartnerAddresses)
                {
                    // Внутри Console.WriteLine будет вызван метод ToString для
                    // экземпляра класса PartnerAddress, у которого этот метод переопределён.
                    // https://source.dot.net/#System.Private.CoreLib/TextWriter.cs,09da57c2c21a3a44
                    Console.WriteLine(address);
                }
    
                // Способ 2.
                //for (int i = 0; i < data.PartnerAddresses.Count; i++)
                //{
                //    Console.WriteLine(data.PartnerAddresses[i]);
                //}
            }
        }
    }


    TriggerData.cs
    using System.Collections.Generic;
    using System.Text.Json.Serialization;
    
    namespace ConsoleApp
    {
        public class TriggerData
        {
            [JsonPropertyName("партнерАдреса")]
            public List<PartnerAddress> PartnerAddresses { get; set; }
        }
    }


    PartnerAddress.cs
    using System.Text.Json.Serialization;
    
    namespace ConsoleApp
    {
        public class PartnerAddress
        {
            [JsonPropertyName("тип")]
            public string Type { get; set; }
    
            [JsonPropertyName("страна")]
            public string Country { get; set; }
    
            [JsonPropertyName("регион")]
            public string Region { get; set; }
    
            [JsonPropertyName("город")]
            public string City { get; set; }
    
            [JsonPropertyName("представление")]
            public string Presentation { get; set; }
    
            public override string ToString()
            {
                return $"{Type}, {Country}, {Region}, {City}, {Presentation}";
            }
        }
    }


    PartnerData.json файл должен быть сохранён в UTF-8 кодировке
    {
      "партнерАдреса": [
        {
          "тип": "тип1",
          "страна": "страна1",
          "регион": "регион1",
          "город": "город1",
          "представление": "представление1"
        },
        {
          "тип": "тип2",
          "страна": "страна2",
          "регион": "регион2",
          "город": "город2",
          "представление": "представление2"
        },
        {
          "тип": "null",
          "страна": "null",
          "регион": "null",
          "город": "null",
          "представление": "null"
        },
        {
          "тип": "тип3",
          "страна": "страна3",
          "регион": "регион3",
          "город": "город3",
          "представление": "представление3"
        }
    ]
    }


    ConsoleApp.csproj (.NET 5 проект)
    <Project Sdk="Microsoft.NET.Sdk">
    
      <PropertyGroup>
        <OutputType>Exe</OutputType>
        <TargetFramework>net5</TargetFramework>
      </PropertyGroup>
    
      <ItemGroup>
        <None Update="PartnerData.json">
          <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
        </None>
      </ItemGroup>
    
    </Project>


    61284df6cbd4b767243491.png
    Ответ написан
    Комментировать
  • Как работают статические поля в C#?

    Casper-SC
    @Casper-SC
    Программист (.NET)
    Константа вычисляется статически на этапе компиляции. Константы подставляются в виде литералов в места использования этих констант. Если создать отдельную сборку только для констант, сослаться на эту сборку из основного проекта, собрать проект, то эту сборку можно будет удалить и всё будет работать, так как в основном проекте не будет ссылок на классы этой сборки, все константы будут подставлены в виде литералов. Так же изменение в сборке с константами потребует пересобрать сборку, которая использует константы.
    Здесь наглядный пример.

    readonly поле - это поле только для чтения, которое можно задать в конструкторе типа, в котором оно определено или в месте объявления поля. Если поле помечено модификатором static, то его значение можно задать только в статическом конструкторе типа, в котором оно определено или в месте объявления поля.
    Ответ написан
    Комментировать
  • Разработка веб-сайта с помощью ASP.NET. С Чего начать?

    Casper-SC
    @Casper-SC
    Программист (.NET)
    Скоро выходит книга, которая переводилась с участием .NET сообщества и нацелена на .NET 5.0.
    ASP.NET Core в действии Оригинальное название: ASP.Net Core In Action, 2nd Ed
    ISBN: 978-5-97060-550-9
    Дата выхода: сентябрь 2021 года

    Согласен с автором другого ответа, так же есть хорошая книга (лежит бумажная версия рядом со мной):
    ASP.NET Core 3 с примерами на C# для профессионалов, 8-е издание | Фримен Адам
    Ответ написан
  • Как решить быстрое закрытие программы?

    Casper-SC
    @Casper-SC
    Программист (.NET)
    Вот так можно написать класс сканер, который получает данные асинхронно. Использовать его можно таким образом в любом типе приложений. Например, в WPF приложение не будет зависать, если, скажем, запустить сканирование по клику на кнопке.

    Обрати ещё внимание на метод с Task.Factory.StartNew и параметром TaskCreationOptions.LongRunning. Для сканирования папок, думаю использовать стоит.
    using System;
    using System.Collections.Generic;
    using System.Threading.Tasks;
    
    namespace ConsoleApp
    {
        class Program
        {
            static async Task Main(string[] args)
            {
                try
                {
                    // Создаём экземпляр класса
                    var scanner = new Scanner();
                    // Вызываем асинхронный метод Scan, метод работает
                    // какое-то время, возвращает результат.
                    var data = await scanner.Scan();
                    foreach (var item in data)
                    {
                        // Выводим на консоль.
                        Console.WriteLine(item);
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex);
                }
            }
        }
    
        public class Scanner
        {
            public Task<List<string>> Scan()
            {
                return Task.Run(async () =>
                {
                    var results = new List<string>();
    
                    for (int i = 0; i < 10; i++)
                    {
                        // Делаем правильную задержку (имитация долгой работы для примера).
                        await Task.Delay(250);
                        // Собираем данные
                        results.Add(DateTimeOffset.Now.ToLocalTime().ToString());
                    }
    
                    return results;
                });
            }
    
            public async Task<List<string>> ScanVersion2()
            {
                return await Task.Factory.StartNew(async () =>
                {
                    var results = new List<string>();
    
                    for (int i = 0; i < 10; i++)
                    {
                        // Делаем правильную задержку (имитация долгой работы для примера).
                        await Task.Delay(250);
                        // Собираем данные
                        results.Add(DateTimeOffset.Now.ToLocalTime().ToString());
                    }
    
                    return results;
                }, TaskCreationOptions.LongRunning)
                    .Unwrap() // Без этого возвращается Task<List<string>>, а не List<string>
                    .ConfigureAwait(false);
            }
        }
    }


    Стоит почитать книгу "Конкурентность в C#. Асинхронное, параллельное и многопоточное программирование"
    Скриншот сделан с видео: https://youtu.be/lh8cT6qI-nA?t=1123

    612185e7a4563153795281.jpeg
    Ответ написан
    1 комментарий
  • Как создать внедряемую dll?

    Casper-SC
    @Casper-SC
    Программист (.NET)
    Документация по команде dotnet new
    В командной строке:
    dotnet new classlib -n "LibraryName" -lang "C#" -o "D:\Projects\LibraryName"

    Через Visual Studio интуитивно понятно как создать новый проект.
    Ответ написан
    Комментировать
  • Как организовать Update в window forms?

    Casper-SC
    @Casper-SC
    Программист (.NET)
    using System;
    using System.Windows.Forms;
    
    namespace WinFormsApp
    {
        public partial class MainForm : Form
        {
            private readonly Random _random;
            private readonly Timer _timer;
    
            public MainForm()
            {
                InitializeComponent();
    
                _random = new Random();
                _timer = new Timer();
                _timer.Interval = 500;
                _timer.Tick += OnTimerTick;
            }
    
            private void OnFormLoad(object sender, EventArgs e)
            {
                _timer.Start();
            }
    
            private void OnTimerTick(object sender, EventArgs e)
            {
                label.Text = _random.Next(0, 1000).ToString();
            }
        }
    }
    Ответ написан
    Комментировать
  • Почему иногда текст 2 раза пишется, а не 1 раз?

    Casper-SC
    @Casper-SC
    Программист (.NET)
    Для решения твоей проблемы тебе нужно написать твой обработчик события загрузки фрейма как показано ниже и убрать отовсюду вызов Invoke. Асинхронные методы на то и возвращают таски, чтобы в том числе можно было работать в UI потоке (основной код писать) и он не зависал.

    Если на странице несколько фреймов, то этот обработчик вызовется, когда буде загружен каждый из них
    private readonly string url = "https://kad.arbitr.ru/Card?number=";
    
    private void OnWebBrowserFrameLoadEnded(object sender, FrameLoadEndEventArgs e)
    {
        Debug.WriteLine($"{nameof(OnWebBrowserFrameLoadEnded)}. " +
                        $"Frame.IsMain: {e.Frame.IsMain.ToString()}; e.Url: {e.Url};");
    
        if (e.Frame.IsMain && e.Url.Contains(url))
        {
            Invoke((MethodInvoker)(async () =>
            {
                await UpdateData();
            }));
        }
    }


    Используй логирование, иначе ты так устанешь баги дебажить. Обычно логеры умеют писать в логи номер потока в том числе.

    ChromiumWebBrowser.FrameLoadEnd
    Ответ написан
    Комментировать
  • Наиболее исчерпывающее руководство\курс по EF?

    Casper-SC
    @Casper-SC
    Программист (.NET)
    В дополнение к предложенной документации в другом ответе можно посмотреть такую книгу:
    Entity Framework Core 2 для ASP.NET Core MVC для профессионалов | Фримен Адам (ISBN: 978-5-907114-86-9)
    Ответ написан
    Комментировать
  • Как сохранить значения переменных после перезапуска в C#?

    Casper-SC
    @Casper-SC
    Программист (.NET)
    Пример сохранения и чтения файла. Есть ещё много других способов. Для поддержки версий файла нужно внутри репозитория создать Dictionary{TKey, TValue}, где TKey - это номер версии, а TValue - сериализатор, десериализатор файла (каждый пишет и читает по своему). Далее, когда читаешь файл, то сначала читаешь его версию, а потом уже вызываешь нужную версию сериализатора и десериализатора.

    Program.cs
    using System;
    using System.Diagnostics;
    using System.IO;
    using System.Threading.Tasks;
    
    namespace GameSaveExample
    {
        class Program
        {
            static async Task Main(string[] args)
            {
                try
                {
                    var rootDirectory = Path.Combine(
                        Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),
                        "AppName");
    
                    using var repository = new GameSaveRepository(rootDirectory, "SaveFile.bin");
                    Console.WriteLine("Первоначальная загрузка данных и вывод на экран:");
                    SaveData data = await repository.Load();
                    Display(data);
    
                    Console.WriteLine("Сохраняем изменённые данные и выводим на экран:");
                    data.Id += 5;
                    await repository.Save(data);
                    Display(data);
    
                    Console.WriteLine("-------------------------");
                    Console.WriteLine("Загружаем данные из файла и выводим на экран:");
                    data = await repository.Load();
                    Display(data);
    
                    Process.Start("explorer.exe", rootDirectory);
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex);
                }
            }
    
            private static void Display(SaveData data)
            {
                Console.WriteLine($"Version: {data.Version}, ID: {data.Id}");
            }
        }
    }


    GameSaveRepository.cs
    using System;
    using System.Diagnostics;
    using System.IO;
    using System.Threading;
    using System.Threading.Tasks;
    
    namespace GameSaveExample
    {
        /// <summary>
        /// Класс, который умеет сохранять данные и загружать.
        /// </summary>
        public class GameSaveRepository : IDisposable
        {
            private readonly string _rootDirectory;
            private readonly string _fileName;
            private readonly string _pathToFile;
            private readonly SemaphoreSlim _semaphore;
    
            public GameSaveRepository(string rootDirectory, string fileName)
            {
                _rootDirectory = rootDirectory;
                _fileName = fileName;
                _pathToFile = Path.Combine(_rootDirectory, fileName);
                _semaphore = new SemaphoreSlim(1);
            }
    
            public async Task<SaveData> Load()
            {
                await _semaphore.WaitAsync();
                var data = new SaveData();
                try
                {
                    await Task.Run(() =>
                    {
                        if (File.Exists(_pathToFile))
                        {
                            using var stream = File.OpenRead(_pathToFile);
                            using var reader = new BinaryReader(stream);
                            data.Version = reader.ReadInt32();
                            data.Id = reader.ReadInt32();
                        }
                    });
                    return data;
                }
                catch (Exception ex)
                {
                    Debug.WriteLine(ex);
                    throw;
                }
                finally
                {
                    _semaphore.Release();
                }
            }
    
            public async Task Save(SaveData data)
            {
                await _semaphore.WaitAsync();
                try
                {
                    await Task.Run(() =>
                    {
                        if (!Directory.Exists(_rootDirectory))
                        {
                            Directory.CreateDirectory(_rootDirectory);
                        }
    
                        using var stream = File.OpenWrite(_pathToFile);
                        using var writer = new BinaryWriter(stream);
                        writer.Write(data.Version);
                        writer.Write(data.Id);
                    });
                }
                catch (Exception ex)
                {
                    Debug.WriteLine(ex);
                    throw;
                }
                finally
                {
                    _semaphore.Release();
                }
            }
    
            public void Dispose()
            {
                _semaphore?.Dispose();
            }
        }
    }


    SaveData.cs
    namespace GameSaveExample
    {
        public class SaveData
        {
            /// <summary>
            /// Версия формата файла. Добавил, удалил или изменил свойство, тогда поднимаем версию.
            /// На каждую версию свой класс сериализатор-десериализатор.
            /// </summary>
            public int Version { get; set; }
    
            /// <summary>
            /// Какие-то данные.
            /// </summary>
            public int Id { get; set; }
        }
    }
    Ответ написан
    Комментировать
  • Как впихнуть компилятор в бота телеграм?

    Casper-SC
    @Casper-SC
    Программист (.NET)
    По ссылкам есть примеры кода, как компилить на лету. Как методы пихать в исходники и т.д. это другой и достаточно простой вопрос.
    Dynamically compile and run code using .NET Core 3.0
    Вот пример от Microsoft
    Cross-Platform Code Generation with Roslyn and .NE...
    Ответ написан
    Комментировать
  • Как переопределить метод, чтобы он создавал и возвращал копию объекта, из которого вызывается?

    Casper-SC
    @Casper-SC
    Программист (.NET)
    Как-то так это делается.

    Кстати, в производном классе вместо
    public override Base CreateCopy()
    можно указать
    public override Derivative CreateCopy()
    и это будет работать. Насколько помню, это нововведение новой версии C#. Вот в справке написано, что версии C# 9.

    using System;
    
    namespace ConsoleApp
    {
        class Program
        {
            static void Main(string[] args)
            {
                var objectBase = new Base("Base");
                var objectDerivative = new Derivative("Derivative", '7');
    
                var copyBase = objectBase.CreateCopy();
                var copyDerivative = objectDerivative.CreateCopy();
    
                Console.WriteLine(copyBase);
                Console.WriteLine(copyDerivative);
            }
        }
    
        public class Base
        {
            private readonly string _text;
    
            public string Text
            {
                get { return _text; }
            }
    
            public Base(string text)
            {
                _text = text;
            }
    
            public virtual Base CreateCopy()
            {
                return new Base(Text);
            }
    
            public override string ToString()
            {
                return $"{nameof(Text)}: {Text}";
            }
        }
    
        public class Derivative : Base
        {
            private readonly char _symbol;
    
            public char Symbol
            {
                get { return _symbol; }
            }
    
            public Derivative(string text, char symbol)
                : base(text)
            {
                _symbol = symbol;
            }
    
            public override Base CreateCopy()
            {
                return new Derivative(Text, Symbol);
            }
    
            public override string ToString()
            {
                return $"{nameof(Text)}: {Text}, {nameof(Symbol)}: {Symbol}";
            }
        }
    }
    Ответ написан
    Комментировать
  • Как шифровать и расшифровывать строки(с посылом и получением строки)?

    Casper-SC
    @Casper-SC
    Программист (.NET)
    Можно использовать библиотеку или подсмотреть реализацию:
    https://github.com/2Toad/Rijndael256
    https://www.nuget.org/packages/Rijndael256.Core/3.2.5

    Почитай главу 3 в книге: Advanced ASP.NET Core 3 Security. Understanding Hacks, Attacks, and Vulnerabilities to Secure Your Website. Узнаешь о проблемах шифрования текста, к примеру и вообще увидишь исходники примеров, как надо. Книгу можно купить на Amazon для приложения для Windows, которое называется Kindle.

    string password = "sKzvYk#1Pn33!YN";  // The password to encrypt the data with
    string plaintext = "Top secret data"; // The string to encrypt
    
    // Encrypt the string
    string ciphertext = Rijndael.Encrypt(plaintext, password, KeySize.Aes256);
    
    // Decrypt the string
    plaintext = Rijndael.Decrypt(ciphertext, password, KeySize.Aes256);
    Ответ написан
    Комментировать
  • Актуальна ли книга C# 2.0 для 8.0?

    Casper-SC
    @Casper-SC
    Программист (.NET)
    Вот здесь описаны изменения от версии к версии. Отличия существенны.
    Ответ написан
    Комментировать
  • К чему привязать ProgressBar c#?

    Casper-SC
    @Casper-SC
    Программист (.NET)
    Нужно в классе "шифраторе" создать событие. Лучше всего шифровать файл вызвав Task.Factory.StartNew, а в конструкторе "шифратора" захватить текущий контекст синхронизации (SynchronizationContext) и по мере шифрования очередной части потока байт вызывать у контекста синхронизации метод Post (он не ждёт пока обработчик события отработает до конца) и внутри него уже вызывать событие ProgressChanged у "шифратора".

    Чтобы понять, что я имею ввиду, смотри код здесь: С# Taks и Invoke почему то блокируется форма?
    Ответ написан
  • Как организовать постоянное обновление DataGrid в отдельном потоке?

    Casper-SC
    @Casper-SC
    Программист (.NET)
    Как организовать постоянное обновление DataGrid в отдельном потоке, чтобы при этом DataGrid был доступен, т.к. планируется добавить возможность выбирать строку из DataGrid и смотреть подробную информацию.

    Нельзя обновлять элементы UI из не UI потока. Можно получать данные в другом потоке, но обновлять UI нужно из UI потока. Я бы просто пробегал по ObservableCollection<{T}>, где T это класс, реализующий интерфейс INotifyPropertyChanged и обновлял нужные объекты уже в UI потоке. Судя по всему, проект не придерживается паттерна MVVM, а лучше бы придерживался.

    Список процессов нужно получать как раз в Task.Run(...), а вот вызывать обновление процессов в UI через Dispatcher или SynchronizationContext.

    Посмотри мои ответы здесь:
    Как осуществить ввод и вывод данных WPF?
    Здесь про Task.Delay и вообще цикл в Task.Run Как сделать цикл на основе ответа на Web запрос в C#?
    Здесь как перенаправлять выполнение через SynchronizationContext в UI поток С# Taks и Invoke почему то блокируется форма?

    Ещё, ожидание в методах, которые запускаются тасками нужно делать через вызов await Task.Delay(...), но точно не через Thread.Sleep(...):
    using System;
    using System.Threading.Tasks;
    
    namespace Tasks
    {
        class Program
        {
            static async Task Main(string[] args)
            {
                // Так
                await Task.Run(async () =>
                {
                    while (true)
                    {
                        await Task.Delay(1000);
                        Console.Write("=");
                    }
                });
    
                // Или так (обрати внимание на Unwrap()) 
                await Task.Factory.StartNew(async () =>
                {
                    while (true)
                    {
                        await Task.Delay(1000);
                        Console.Write("=");
                    }
                }).Unwrap();
            }
        }
    }
    Ответ написан
    1 комментарий
  • Не могу понять, как работает async?

    Casper-SC
    @Casper-SC
    Программист (.NET)
    Конкретно по вопросу: файл открыт в другой программе, скорее всего, на запись в том числе. Логично, что нельзя этот файл ещё раз открыть на запись.
    Конструктор FileStream, используемый в вашем коде FileAccess.ReadWrite:
    public FileStream(string path, FileMode mode) :
                this(path, mode, (mode == FileMode.Append ? FileAccess.Write : FileAccess.ReadWrite), DefaultShare, DefaultBufferSize, DefaultIsAsync)
            { }


    Попробуйте такой код. Он тоже выдаст такую же ошибку, если файл попробовать таким способом открыть только в своём приложении:
    using (FileStream source = new FileStream("NLog.config", FileMode.Open))
    using (FileStream source2 = new FileStream("NLog.config", FileMode.Open))
    using (FileStream target = new FileStream("newPath", FileMode.OpenOrCreate))
    {
        await source.CopyToAsync(target);
    }


    Стоит почитать книгу "Конкурентность в C#. Асинхронное, параллельное и многопоточное программирование"
    Скриншот сделан с видео: https://youtu.be/lh8cT6qI-nA?t=1123

    5fb13cbe569ab013358287.jpeg
    Ответ написан
    Комментировать
  • Как вывести из json только определенные элементы?

    Casper-SC
    @Casper-SC
    Программист (.NET)
    Берёшь свой запрос. Открываешь программу Postman. Отправляешь запрос. Копируешь полученный JSON в буфер обмена. Переходишь на какой-нибудь сайт вроде https://json2csharp.com/ и вставляешь туда JSON. Копируешь полученные классы, правильно именуешь. Параметры генерации классов:
    5fe665235f0a1045486034.png

    Кстати, для поискового запроса (текста) можно попробовать использовать Uri.EscapeUriString

    Подключение быстрого сериализатора System.Text.Json из .NET Core

    RestSharpExample.csproj
    <Project Sdk="Microsoft.NET.Sdk">
    
      <PropertyGroup>
        <OutputType>Exe</OutputType>
        <TargetFramework>netcoreapp3.1</TargetFramework>
      </PropertyGroup>
    
      <ItemGroup>
        <PackageReference Include="RestSharp" Version="106.11.7" />
        <PackageReference Include="RestSharp.Serializers.SystemTextJson" Version="106.11.7" />
      </ItemGroup>
    
    </Project>


    Api/Kinopoisk/KinopoiskService.cs
    using System.Threading.Tasks;
    using System.Web;
    using RestSharp;
    using RestSharp.Serializers.SystemTextJson;
    using RestSharpExample.Api.Kinopoisk.Model;
    
    namespace RestSharpExample.Api.Kinopoisk
    {
        public class KinopoiskService
        {
            private const string API = "https://api.kinopoisk.cloud/";
            private const string TOKEN = "7777";
    
            private readonly RestClient _client;
    
            public KinopoiskService()
            {
                _client = new RestClient(API);
                _client.UseSystemTextJson();
            }
    
            public async Task<SearchResult> SearchAsync(string movieTitle)
            {
                var request = new RestRequest($"movies/search/{HttpUtility.UrlEncode(movieTitle)}/token/{TOKEN}", Method.GET);
                var response = await _client.ExecuteAsync<SearchResult>(request);
                return response.Data;
            }
        }
    }


    Program.cs
    using System;
    using System.Linq;
    using System.Threading.Tasks;
    using RestSharpExample.Api.Kinopoisk;
    using RestSharpExample.Api.Kinopoisk.Model;
    
    namespace RestSharpExample
    {
        class Program
        {
            private KinopoiskService _kinopoisk;
    
            #region Entry point
    
            static async Task Main(string[] args)
            {
                var program = new Program();
                await program.Run(args);
            }
    
            #endregion
    
            private async Task Run(string[] args)
            {
                _kinopoisk = new KinopoiskService();
    
                try
                {
                    string searchRequest = "Дурак";
                    SearchResult result = await _kinopoisk.SearchAsync(searchRequest);
                    Console.WriteLine($"Результаты поиска по запросу \"{searchRequest}\":");
                    if (result.Results.Any())
                    {
                        Display(result.Results.First());
                    }
                    else
                    {
                        Console.WriteLine("Ничего не найдено.");
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex);
                }
            }
    
            private void Display(SearchMovieInfo info)
            {
                Console.WriteLine($"ИД: {info.Id}, Название: {info.Title}, Год: {info.Year}");
            }
        }
    }


    Api/Kinopoisk/Model/SearchResult.cs
    using System.Collections.Generic;
    using System.Text.Json.Serialization;
    
    namespace RestSharpExample.Api.Kinopoisk.Model
    {
        public class SearchResult
        {
            [JsonPropertyName("results")]
            public List<SearchMovieInfo> Results { get; set; }
    
            [JsonPropertyName("pagination")]
            public Pagination Pagination { get; set; }
        }
    }


    Api/Kinopoisk/Model/SearchMovieInfo.cs
    using System.Text.Json.Serialization;
    
    namespace RestSharpExample.Api.Kinopoisk.Model
    {
        public class SearchMovieInfo
        {
            [JsonPropertyName("id")]
            public string Id { get; set; }
    
            [JsonPropertyName("id_kinopoisk")]
            public int IdKinopoisk { get; set; }
    
            [JsonPropertyName("title")]
            public string Title { get; set; }
    
            [JsonPropertyName("description")]
            public string Description { get; set; }
    
            [JsonPropertyName("year")]
            public int Year { get; set; }
    
            [JsonPropertyName("poster")]
            public string Poster { get; set; }
    
            [JsonPropertyName("rating_kinopoisk")]
            public double? RatingKinopoisk { get; set; }
    
            [JsonPropertyName("rating_imdb")]
            public double? RatingImdb { get; set; }
        }


    Api/Kinopoisk/Model/Pagination.cs
    using System.Text.Json.Serialization;
    
    namespace RestSharpExample.Api.Kinopoisk.Model
    {
        public class Pagination
        {
            [JsonPropertyName("current_page")]
            public string CurrentPage { get; set; }
    
            [JsonPropertyName("end_page")]
            public string EndPage { get; set; }
    
            [JsonPropertyName("total_pages")]
            public int TotalPages { get; set; }
        }
    }
    Ответ написан
    Комментировать
  • WPF vs UWP в 2021?

    Casper-SC
    @Casper-SC
    Программист (.NET)
    • Между UWP и WPF есть ещё отличие в жизненном цикле приложения. UWP приложение не совсем тоже самое, что и WPF.
    • В UWP преобладает страничный режим. Там всё построено на переходах между страницами.
    • Приложения UWP устанавливаются из Microsoft Store.
    • Приложения UWP требуют включения разных разрешений для приложения.

    5fe41c979dcc6193298625.png
    Ответ написан
    5 комментариев
  • Почему в WPF не работает перенаправление на другое окно?

    Casper-SC
    @Casper-SC
    Программист (.NET)
    Посмотри рабочий пример реализации здесь:
    Как осуществить переход между страницами в Windows Presentation Foundation?

    У тебя просто открыто окно и в нём вызывается работа сервиса. Это не означает, что MainWindow закроется и откроется новое окно. Нужно использовать или Frame или NavigationWindow (справка поддерживает русский язык, смени en-us на ru-ru).
    Ответ написан
    Комментировать