Форум программистов, компьютерный форум, киберфорум
C#: WPF, UWP и Silverlight
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.53/40: Рейтинг темы: голосов - 40, средняя оценка - 4.53
2 / 1 / 1
Регистрация: 17.11.2020
Сообщений: 105
UWP

Разбор MVVM подхода с использованием API и Json

04.02.2022, 21:07. Показов 9427. Ответов 126
Метки mvvm, uwp (Все метки)

Студворк — интернет-сервис помощи студентам
Доброго времени суток,

Как уже писал, перехожу на подход MVVM и сталкиваюсь с проблемами, шерстил форум, но не нашел подходящие решение для моего случая. Очень буду благодарен за помощь.

Логика следующая, пользователей вводит номер телефона, по апи идет запрос и я получаю ответ в виде JSON, и если JSON приходит в response, то панель с смс должна появится. Если номер не правильный то приходит в error значение.

Проблема вот в чем. Как мне вернуть данные из Model в ViewModel, не используя статический класс или свойство ? Да в принципе, как правильно управлять данными которые пришли в model и передать их в Viewmodel на примере JSON.


View:
XML
1
2
3
4
5
6
7
                        <StackPanel>
                            <TextBox x:Uid="Phone" Text="{x:Bind onsignVM.user_login,Mode=TwoWay}" />
                            <StackPanel Visibility="{x:Bind responsesignVM.visibilitysmstextblock, Mode=OneWay}" >
                                <TextBox x:Uid="SmsText"  />
                            </StackPanel>
                            <Button  x:Uid="SignSms" Click="{x:Bind onsignVM.Poke}"  />
                        </StackPanel>
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
using Test.ViewModels;
 
namespace Test.Views
{
    public sealed partial class Sign : Page
    {
        public Sign()
        {
            InitializeComponent();
        }
 
    public AuthorizationTest onsignVM { get; } = new AuthorizationTest();
    public LoginformTest responsesignVM { get; } = new LoginformTest();
 
}
}
ViewModel:

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Text.Json;
using Test.Models;
using Windows.Storage;
using Windows.UI.Xaml;
 
namespace Test.ViewModels
{
    public class SignVM
    {
 
 
    }
 
    public class LoginformTest : INotifyPropertyChanged
    {
        private int _error { get; set; }
        private string _response { get; set; }
        private Visibility _visibilitysmstextblock { get; set; }
 
        public Visibility visibilitysmstextblock
        {
            get { return _visibilitysmstextblock = _response == null ? Visibility.Collapsed : Visibility.Visible; }
            set { _visibilitysmstextblock = value; OnPropertyChanged("visibilitycountnewtoday"); }
        }
        public int error 
        {
            get { return _error; }
            set { _error = value; OnPropertyChanged("error"); }
        }
        public string response 
        {
            get { return _response; }
            set { _response = value; OnPropertyChanged("response"); }
        }
 
        public event PropertyChangedEventHandler PropertyChanged;
        private void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }
 
 
 
 
 
    public class AuthorizationTest : INotifyPropertyChanged
    {
        
        private string _user_login { get; set; }
        private string _hwid { get; set; }
        private string _device { get; set; }
 
        public string user_login
        {
            get { return _user_login; }
            set { _user_login = value; OnPropertyChanged("user_login"); }
        }
        public string hwid
        {
            get { return _hwid; }
            set { _hwid = value; OnPropertyChanged("hwid"); }
        }
        public string device
        {
            get { return _device; }
            set { _device = value; OnPropertyChanged("device"); }
        }
 
 
        public void Poke()
        {
            ApplicationDataContainer localSettings = ApplicationData.Current.LocalSettings;
            ApplicationDataCompositeValue Settings = (ApplicationDataCompositeValue)localSettings.Values["Settings"];
 
            AuthorizationTest postData = new AuthorizationTest
            {
                user_login = this.user_login,
                hwid = (string)Settings["Hwid"],
                device = (string)Settings["Device"],
            };
 
 
            byte[] data = JsonSerializer.SerializeToUtf8Bytes(postData);
 
           SignM.Connect(data);
    }
 
 
    public event PropertyChangedEventHandler PropertyChanged;
    private void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
 
 
 
}
}
Model:

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
using Test.ViewModels;
using System;
using System.IO;
using System.Net;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
using Windows.Storage;
using Windows.UI.Xaml.Controls;
 
namespace Test.Models
{
    public class SignM
    {
        public static LoginformTest RootStatic { get; set; }
 
        public static void Connect(byte[] data)
        {
            ApplicationDataContainer localSettings = ApplicationData.Current.LocalSettings;
            ApplicationDataCompositeValue Settings = (ApplicationDataCompositeValue)localSettings.Values["Settings"];
 
            HttpWebResponse response;
            try
            {
 
                HttpWebRequest request = (HttpWebRequest)WebRequest.Create(new Uri(Settings["UriAPI"] + "/user/auth"));
                request.Method = "POST";
                request.Headers.Add("CLIENTKEY", (string)Settings["Test"]);
                request.ContentType = "application/json";
                request.ContentLength = data.Length;
 
                using (Stream stream = request.GetRequestStream())
                {
                    stream.Write(data, 0, data.Length);
                }
 
                /// This will have statii from 200 to 30x
                response = (HttpWebResponse)request.GetResponse();
            }
            catch (WebException ex)
            {
                /// Statii 400 to 50x will be here
                response = (HttpWebResponse)ex.Response;
            }
 
            if (response != null)
            {
 
                using (StreamReader stream = new StreamReader(response.GetResponseStream(), Encoding.UTF8))
                {
                    try
                    {
                        RootStatic = JsonSerializer.Deserialize<LoginformTest>(stream.ReadToEnd());
 
                    }
 
                    catch (JsonException ex)
                    {
 
                    }
                }
  
            }
 
            else
            {
 
            }
 
        }
 
    }
}
Чего я хочу добиться, чтобы дессериализация происходила в LoginformTest и от полученых данных появлялась панель или нет, с блоком для ввода смс. За это отвечает _visibilitysmstextblock. Помимо этого, я понимаю, что в Model не должно быть статических свойств, как мне вызывать connect без статики из ViewModel ?

Так же я понимаю, что возможно здесь ошибки подхода MVVM, любые поправки с теплотой приму
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
04.02.2022, 21:07
Ответы с готовыми решениями:

Вывод данных JSON в консоль с использованием API токена
Вечер в хату, форумчане! Мне нужно вытащить данные с сервера с помощью API токена и вывести их на консоль, с данной темой столкнулся...

Создание программ с использованием структурного подхода
Привет всем, помогите пожалуйста решить любую из задачек: Сведения об ученике состоят из его имени, фамилии и названия класса (года...

Напишите программу (с использованием ООП подхода)
Напишите программу (с использованием ООП подхода), что отвечает следующим требованиям: • Пользователь вводит интервал (например, ). •...

126
2 / 1 / 1
Регистрация: 17.11.2020
Сообщений: 105
06.02.2022, 12:23  [ТС]
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Если в мой вариации, то Connect - это приватный метод отправляющий массив байт и получающий массив байт.
Полученный ответ разбирают уже публичные методы Модели в конкретные типы - возможно ваши пользовательские DTO.
Да я уже понял вашу мысль, я вот сделал, классно получилось. Я только поменял везде на string, так как в байтах в стримридер очень трудно потом все конвертировать, точнее это лишний код, поэтому я просто передаю JSON в стринги обратно из connect и дессерилизирую его в методе Authorizat. И потом отправляю ответ уже во VM, если true то появляется панель. Соотствественно во VM у меня

C#
1
2
3
4
5
public SignM onSignM { get; } = new SignM();
 
______________________________
 bool test = onSignM.Authorizat(data);
______________________________
Потому что это пока не главная VM, я могу обьявлять спокойно onSignM в ней. Надеюсь мою мысль вы поняли и сможете указать на ошибку, если я ее доспустил ?!
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16166 / 11286 / 2892
Регистрация: 21.04.2018
Сообщений: 33,175
Записей в блоге: 2
06.02.2022, 13:00
Цитата Сообщение от Ihave Посмотреть сообщение
Надеюсь мою мысль вы поняли и сможете указать на ошибку, если я ее доспустил ?!
Всё правильно.

В результате вы должны получить абстрактную Модель, которая получает какие-то данные в параметрах метода и возвращает результат.
А как она это делает: обращается в Web, в локальную БД, каким-то образом вычисляет и т.п. - никто кроме самой Модели знать не должен.
Все параметры необходимые для работы её методов, если параметров самого метода не хватает (адрес сервера, строка соединяя и т.п.), в Модель должен передавать App.
Это можно делать непосредственно в App. Тогда там будет создаваться экземпляр Модели и внедряться в VM.
Но App может внедрить это и в VM, а VM уже сама внедрит эти параметры в Модель при создании экземпляра.
1
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16166 / 11286 / 2892
Регистрация: 21.04.2018
Сообщений: 33,175
Записей в блоге: 2
06.02.2022, 17:48
Цитата Сообщение от Ihave Посмотреть сообщение
поэтому я просто передаю JSON в стринги обратно из connect и дессерилизирую его в методе Authorizat
Кстати, вспомнилось, я когда-то делал торгового бота, и там типично по нескольку сот сообщений в секунду приходило.
Собирать ответ в строку, а потом десериализовать стало накладно - появлялась целая куча мусора и используемая память быстро росла.
А когда вызывался мусорщик, появлялись лаги.
А лаг потенциально это пропущенная сделка и удар по кошельку клиента.

Поэтому я там сериализовывал входящий поток сразу в объект, без промежуточного создания строки.
Нагрузка на память резко уменьшилась.
А лаги совершенно пропали.
0
2 / 1 / 1
Регистрация: 17.11.2020
Сообщений: 105
06.02.2022, 19:52  [ТС]
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Это можно делать непосредственно в App. Тогда там будет создаваться экземпляр Модели и внедряться в VM.
а как это сделать ? Через инициализацию ?

C#
1
 SignM.Initialize();
Я потом буду получать Token и мне надо будет его хранить и после закрытия приложения, поэтому у меня там проверка, если в локальном хранилище отсутствует Token, то появляется форма для ввода телефона и тд. Если он есть, вызывается метод авторизации напрямую по токену.

Цитата Сообщение от Элд Хасп Посмотреть сообщение
Все параметры необходимые для работы её методов, если параметров самого метода не хватает (адрес сервера, строка соединяя и т.п.), в Модель должен передавать App.
получается я храню, токен и какие то постоянные значение в App и передаю их уже в модель ? При помощи инициализации ? Есть пример какой нибудь ?

Цитата Сообщение от Элд Хасп Посмотреть сообщение
Кстати, вспомнилось, я когда-то делал торгового бота, и там типично по нескольку сот сообщений в секунду приходило.
У меня впринципе такого нету, чтобы был постоянный поток, за исключением обновлений каких то параметров раз в 5 минут, но подумаю как можно поток передавать, потому что я попробывал поток передавать и он жаловался, что я его не закрыл, хотя я написал явный параметр закрытия
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16166 / 11286 / 2892
Регистрация: 21.04.2018
Сообщений: 33,175
Записей в блоге: 2
06.02.2022, 20:24
Цитата Сообщение от Ihave Посмотреть сообщение
а как это сделать ? Через инициализацию ?
Типовой подход: Прослушивать изменения в Model из ViewModel

Добавлено через 1 минуту
Цитата Сообщение от Ihave Посмотреть сообщение
Я потом буду получать Token и мне надо будет его хранить и после закрытия приложения, поэтому у меня там проверка ...
Это тоже делаете в App - настройки приложения его прерогатива.

Добавлено через 5 минут
Цитата Сообщение от Ihave Посмотреть сообщение
, но подумаю как можно поток передавать, потому что я попробывал поток передавать и он жаловался, что я его не закрыл, хотя я написал явный параметр закрытия
Я сейчас не помню деталей, но мудохоться пришлось изрядно.
Там я делал какой-то хитрый парсинг с чтением заголовка потока.
Но в вашем случае, думаю можно поступить проще.

Создайте Connect с дженериком:
C#
1
     public static T Connect<T>(.....)
И сериализуйте поток в тип дженерика.
0
2 / 1 / 1
Регистрация: 17.11.2020
Сообщений: 105
08.02.2022, 19:35  [ТС]
Элд Хасп, В итоге у меня получилось так:

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
using System;
using System.IO;
using System.Net;
 
namespace Test.Models
{
    public class SignM
    {
        private string Test { get; } = "blaaaaaaa";
        private Uri UriApi { get; } = new Uri("https://test");
 
        /// <summary>
        /// Авторизация и получение токена. 
        /// </summary>
        public HttpWebResponse Connect(byte[] data)
         {
            HttpWebResponse response;
            try
            {
                HttpWebRequest request = (HttpWebRequest)WebRequest.Create(UriApi);
                request.Method = "POST";
                request.Headers.Add("CLIENTKEY", Test);
                request.ContentType = "application/json";
                request.ContentLength = data.Length;
 
                using (Stream stream = request.GetRequestStream())
                {
                    stream.Write(data, 0, data.Length);
                }
 
                /// Код состояния HTTP 200 до 30x
                response = (HttpWebResponse)request.GetResponse();
            }
            catch (WebException ex)
            {
                /// Код состояния HTTP ошибок 400 до 50x
                response = (HttpWebResponse)ex.Response;
            }
 
            if (response != null)
            {
                /// Получил данные
                return response;
            }
 
            else
            {
                /// Нету подключения к интернету
                return null;
            }
        }
    }
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Типовой подход: Прослушивать изменения в Model из ViewModel
Так и не понял, как мне например передавать UriApi и ключ в модель из APP. Пришлось просто обьявить в самой модели.

В ViewModel у меня получается идет и дессериализация и все проверки и вывод окна если нету интернета ? Это правильно, что все это будет находится именно там ? а View служит исключительно отображением и кое какими свойствами. Например переключение видимости панель.
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16166 / 11286 / 2892
Регистрация: 21.04.2018
Сообщений: 33,175
Записей в блоге: 2
08.02.2022, 19:48
Ihave, вы же хотите сделать правильный MVVM - тему же с этого начали.
Если так то Модель должна полностью инкапсулировать "настоящие" Данные.
А у вас метод Connect возвращает HttpWebResponse.
А если завтра эта модель будет работать с БД, или с локальным набором файлов XAML, то как она вернёт HttpWebResponse?
Вам придётся изменять возвращаемый метод.
А так как этот метод публичный, то это может привести к изменению во всех слоях приложения.
То есть у вас совершенно нет никакой абстракции данных, а это нарушение не то, что MVVM, а общих принципов, правил ООП, SOLID.
0
2 / 1 / 1
Регистрация: 17.11.2020
Сообщений: 105
08.02.2022, 20:12  [ТС]
Цитата Сообщение от Элд Хасп Посмотреть сообщение
А если завтра эта модель будет работать с БД, или с локальным набором файлов XAML, то как она вернёт HttpWebResponse?
Модель в теории даже не будет работать с БД, только общение с сервером. В чем принципиальность возвращение данных ? Если она так же будет возвращать string или byte. Передача просто JSON обратно в виде string, разве будет более инкапсулировано?

Цитата Сообщение от Элд Хасп Посмотреть сообщение
А так как этот метод публичный, то это может привести к изменению во всех слоях приложения.
Здесь получается так, что эта модель отвечает только за вход, помимо этой модели будет еще одна которая немного другие параметры имеет. И вторая модель будет уже иметь приватный метод и отдельные методы которые будут вызываться методами внутри метода.

Цитата Сообщение от Элд Хасп Посмотреть сообщение
вы же хотите сделать правильный MVVM - тему же с этого начали.
Поэтому я и пишу сюда
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16166 / 11286 / 2892
Регистрация: 21.04.2018
Сообщений: 33,175
Записей в блоге: 2
08.02.2022, 23:35
Цитата Сообщение от Ihave Посмотреть сообщение
В чем принципиальность возвращение данных ?
Вы же задали вопрос как правильно сделать в MVVM.
Так вот инкапсуляция данных это важный принцип не то, что MVVM, а даже с точки зрения ООП.
Если бы вопрос был "А бы как, но лишь бы работало" - тогда другое дело.

И даже более, за связь с Хранилищем (без разницы это БД или WEB сервер) обычно отвечает специально выделенный слой в Модели - Репозиторий.
Чаще всего его используют с БД, но концептуально он применяется для любого типа источника данных.

Цитата Сообщение от Ihave Посмотреть сообщение
И вторая модель будет уже иметь приватный метод и отдельные методы которые будут вызываться методами внутри метода.
Возможно у нас здесь где-то нарушилось взаимопонимание.
Ссылка на SignM у кого будет?
Если только у другой Модели и App - то такая реализация допустима.
Если же о SignM будут знать View или ViewModel.
То есть по сути, по своей функциональности SignM - это Репозиторий.
И относится надо к нему соответственно.

Цитата Сообщение от Ihave Посмотреть сообщение
И вторая модель будет уже иметь приватный метод и отдельные методы которые будут вызываться методами внутри метода.
Ну, да.
Мы же об этом уже писали. И я думал вы так и сделали: на каждый тип запроса свой метод возвращающий свой тип данных.
А ту обратно, как чёрт из табакерки, выскакивает публичный HttpWebResponse Connect(byte[] data).

Ihave, у меня предложение.
Чтобы меньше заниматься догадками залейте проект на Гит.
Там можно будет посмотреть на все нюансы взаимодействия не задавая лишних вопросов.
0
2 / 1 / 1
Регистрация: 17.11.2020
Сообщений: 105
09.02.2022, 23:18  [ТС]
Элд Хасп,
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Возможно у нас здесь где-то нарушилось взаимопонимание.
Да это моя вина, просто задача на много шире, чем то, c чего началась тема. И когда я начал все переделывать, снова начал трогать код для упрощения чего то. Так сказать свернул с "самурайского пути MVVM" трудно себя переучивать писать код в рамках

Цитата Сообщение от Элд Хасп Посмотреть сообщение
Чтобы меньше заниматься догадками залейте проект на Гит.
Сделано: https://github.com/Odaronil/SignMVVM

Как я уже говорил задача сложней чем я описывал вначале. Если вы готовы помочь давайте рассмотрим "рабочий режим" в рамках обычного входа и больше ничего.

Как сейчас работает:
1)Пользователь открывает программу и видит только текстовое поле с вводом телефона и кнопкой. Вводит номер телефона и нажимает кнопку. По нажатию кнопки идет считывание номера и собирается JSON в VM вместе с некоторыми данными об устройстве.

2) VM обращается к определённой модели у нас это Authorizat, модель Authorizat дополняет URL адреса соответствующий авторизации на сервере и передает массив байтов на отправку на сервер в другую модель Connect.
3) Модель Connect отправляет данные на сервер и получает ответ
a) Eсли нету интернета, возвращает Null сначала в Authorizat потом в VM, происходит повторение вызова Authorizat каждые 5 секунд три раза, в итоге если интернета нету, пользователь должен получить диалоговое окно с тем, что интернета нету и либо он нажмет повторить, снова будет три раза по 5 секунд вызов Авторизация, либо отменит всю операцию.
b) Если все хорошо, Connect возвращает джсон в виде String в Authorizat и сохраняет статус кодов http.

4) Authorizat получила джсон и возвращает его в VM

5) VM получает JSON и дессерелизирует его в класс а затем обрабатывает.

a) Если пользователь ввел все верно и телефон совпадает с базой то показывает Infobar который отображает статус http и информацию о том что смс отправлена и тд, так же появляется поле с вводом смс и кнопкой подтверждения кода смс.
b) Если что то не так, то выводится в том же infobar ошибка и описание ошибки соответствующей коду и панель не появляется.
6) Пользователь вводит смс и повторяется все с теми же моделями, так как раньше поле SetSms было пусто, то сервер понял, что пользователь не вводил смс, но если поле SetSms заполнено, то сервер уже выдаст Token для дальнейшей авторизации или покажет ошибку. Токен необходимо сохранить, чтобы использовать уже его дальше для авторизации и получение других данных от сервера.

Что не получается сделать:
1) Общие правильность написание MVVM, я не уверен, что правильно сделал, так как вы писали, что VM по сути не должно что то делать c данными?!
2) Передача статус состояния HTTP кодов из Connect, не уверен, что правильно так же сделал.
3) Передача данных в модели, такие как доп UrlAPI, хотелось бы избавиться от локального хранилища, но так и не понял как передавать данные из APP в модель. Например UriApi, Device, HWid и тд
4) Так же не уверен в том что я добавил несколько строк кода в код (Например отслеживание нажатия enter) страницы Sign.cs. Так как не знаю как это перенести в VM.
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16166 / 11286 / 2892
Регистрация: 21.04.2018
Сообщений: 33,175
Записей в блоге: 2
10.02.2022, 01:14
Цитата Сообщение от Ihave Посмотреть сообщение
4) Authorizat получила джсон и возвращает его в VM
Это не правильно.
Сериализовать JSON в объект должна Модель.

Цитата Сообщение от Ihave Посмотреть сообщение
1) Общие правильность написание MVVM, я не уверен, что правильно сделал, так как вы писали, что VM по сути не должно что то делать c данными?!
Все проблемы из-за того, что вы строите приложение "от WPF View".
Но у вас не хватает пока знаний и опыта чтобы это правильно сделать.
Начните с того, что построите ПОЛНОСТЬЮ Модель и отдебажите её в КОНСОЛЬНОМ приложении.
Когда у вас будет готовая такая Модель, то большая часть вопросов у вас отпадёт сама собой.

Добавлено через 25 секунд
Цитата Сообщение от Ihave Посмотреть сообщение
Будет время - посмотрю и может быть отвечу более детально.

Добавлено через 2 минуты
При построении Модели из неё не должно выходить ни каких "сырых" данных, только различные готовые объекты: типы общего применения, сущности, DTO и т.п.

Добавлено через 2 минуты
Все JSON, XML, потоки, сокеты, БД и т.д. - это самый нижний слой Модели.
Обычно его выполняют в виде Репозитория.
Но если вам удобнее, привычнее - можете вместо него сделать какой-то сервис.
Но общаться с ним может только Модель и, в крайнем случае, App.
0
2 / 1 / 1
Регистрация: 17.11.2020
Сообщений: 105
10.02.2022, 18:43  [ТС]
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Все проблемы из-за того, что вы строите приложение "от WPF View".
Это не то, что я думаю от View. Обьясню по другому:
Нужно чтобы после ввода телефона, пользователю показывалась панель с смс, если нету интернета то диаголовое окно о том что проблема с интернетом, если какая то ошика, то нужно показать какая и в чем заключается или что успешно все прошло.

Я стараюсь лишь сделать, так как это обусловлено "Техническим заданием" при помощи тех инструментов, которые знаю. Отсюда и ошибки, поэтому и пишу сюда за помощью, так как нацелен сделать все грамотно и с подходом MVVM.

Цитата Сообщение от Элд Хасп Посмотреть сообщение
Сериализовать JSON в объект должна Модель.
Еще раз спрашиваю, может вы не заметили, КАК мне передать потом параметры после дессерилизации в VM? А именно код ошибки HTTP кода, и ошибки Error или положительный ответ.

Если вы еще имеете ввиду что и Сереализация должно проходить в Модели, то как передать все заполненые поля в модель.

Не думаю что такое будет уместно:

C#
1
 public SignVM Authorizat(SignVM data)
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Будет время - посмотрю и может быть отвечу более детально.
Буду очень благодарен.

Цитата Сообщение от Элд Хасп Посмотреть сообщение
При построении Модели из неё не должно выходить ни каких "сырых" данных, только различные готовые объекты: типы общего применения, сущности, DTO и т.п.
Я это понимаю, поэтому и пишу сюда Хотелось бы получить ответ, как все таки правильно то делать(Круто было бы с Реальным КОДОМ).... А не только то что это не правильно....

Цитата Сообщение от Элд Хасп Посмотреть сообщение
Обычно его выполняют в виде Репозитория.
Но если вам удобнее, привычнее - можете вместо него сделать какой-то сервис.
Как я уже говорил, я вообще не против делать все правильно, но прошу тогда, можно какой то код или пример НАГЛЯДНЫЙ. Я понимаю, что гугл не отменяли, но прежде чем сюда писать, я его и смотрел Но либо примеры непонятные для меня или они не подходящие.
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16166 / 11286 / 2892
Регистрация: 21.04.2018
Сообщений: 33,175
Записей в блоге: 2
10.02.2022, 20:36
Цитата Сообщение от Ihave Посмотреть сообщение
КАК мне передать потом параметры после дессерилизации в VM? А именно код ошибки HTTP кода, и ошибки Error или положительный ответ.
Черех свойства объекта возвращаемого методом или через свойство Модели.

Цитата Сообщение от Ihave Посмотреть сообщение
Это не то, что я думаю от View. Обьясню по другому:
Вы думаете от View, и это ваше объяснение ещё раз это поджтверждает.

Вот у вас есть Модель в которой ТОЛЬКо Методы и События.
Свойств нет.
Модель возвращаете ТОЛЬКО DTO-шки.

Теперь каждый вопрос формулируйте так, Какое DTO надо передать Модели и какое DTO она должна вернуть?
Какогда ответили на этот вопрос, то создаёте соответсвующий метод в модели и реализуете его.

Добавлено через 4 минуты
Цитата Сообщение от Ihave Посмотреть сообщение
можно какой то код или пример НАГЛЯДНЫЙ
Можно.
Но проблема в том, что ваше приложение уже разрослось.
И что встроить в него "по простому" не получится.

Поэтому моё предложение: давайте создадим новое приложение с нуля. Сначала реализуем в нем небольшой начальный функционал для закрепления архитектуры (допустим, возьмём только авторизацию логином и паролем). А потом будем наращивать функционал и смотреть чтобы он не ломал архитектуру.

Добавлено через 20 минут
Цитата Сообщение от Ihave Посмотреть сообщение
посмотрю и может быть отвечу более детально.
Посмотрел.
Я думал там вы навертели.
Но там токо авторизация.
В принципе реализовано верно.
Там же Connect приватный метод - тогда это нормально.
А выше здесь в теме вы показывали, что это публичный метод - а вот это неверно.

Добавлено через 16 минут
Единственно, мне не нравится что возвращается стринг, а не поток.
Но если передача не очень частая, то это не важно.

Добавлено через 25 минут
Цитата Сообщение от Ihave Посмотреть сообщение
А именно код ошибки HTTP кода, и ошибки Error или положительный ответ
Измените возвращаемы типы методов:
C#
1
2
3
4
5
6
7
8
9
        public (bool isAuthorizated , int error) Authorizat(string login, string password)
        {
 
        }
          
        private (string json, int error) Connect(byte[] data, string PlusUri)
        {
 
        }
0
2 / 1 / 1
Регистрация: 17.11.2020
Сообщений: 105
10.02.2022, 22:45  [ТС]
Цитата Сообщение от Элд Хасп Посмотреть сообщение
(допустим, возьмём только авторизацию логином и паролем).
Цитата Сообщение от Элд Хасп Посмотреть сообщение
А выше здесь в теме вы показывали, что это публичный метод - а вот это неверно.
Да, я же написал, что ошибку допустил и тд

Цитата Сообщение от Элд Хасп Посмотреть сообщение
Единственно, мне не нравится что возвращается стринг, а не поток.
Этим можно будет заморочиться чуть позже, сейчас главное мне понять полностью на данном примере MVVM и сделать всё правильно.

Цитата Сообщение от Элд Хасп Посмотреть сообщение
Измените возвращаемы типы методов:
C#
1
string login, string password
А если нужно больше двух параметров ? То все равно все передавать в модель и только там делать Сериализацию ?

Я обновил проект на гитхабе, только добавил еще один параметр HttpStatusCode, так как это особеное свойство, которое трудно будет преоброзовать во что то конкретное. будет время посмотрите пожалуйста.
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16166 / 11286 / 2892
Регистрация: 21.04.2018
Сообщений: 33,175
Записей в блоге: 2
11.02.2022, 00:52
Цитата Сообщение от Ihave Посмотреть сообщение
А если нужно больше двух параметров ? То все равно все передавать в модель и только там делать Сериализацию ?
Передаются DTO отражений.
Кортежи удобный способ создания DTO.
Но есть много задач, где нужно создание структур или классов DTO.
0
2 / 1 / 1
Регистрация: 17.11.2020
Сообщений: 105
11.02.2022, 20:29  [ТС]
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Передаются DTO отражений.
Кортежи удобный способ создания DTO.
Но есть много задач, где нужно создание структур или классов DTO.
Когда это более уместно ? Например с логин и паролем это заходит, но если в метод надо 10 параметров передать ? Тоже использовать кортеж или можно передать сразу DTO ?

типо:

C#
1
2
3
4
5
      
public (bool isAuthorizated , int error) Authorizat(SignVM bla)
        {
 
        }
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16166 / 11286 / 2892
Регистрация: 21.04.2018
Сообщений: 33,175
Записей в блоге: 2
11.02.2022, 20:55
Цитата Сообщение от Ihave Посмотреть сообщение
но если в метод надо 10 параметров передать ? Тоже использовать кортеж или можно передать сразу DTO ?
Если набор значений нужен только в одном месте, если не нужно его хранить и передавать куда-то - то проще кортеж.
В DTO вы можете использовать не все свойства, но сигнатура метода от этого не изменится.
А с кортежем для любого изменения в наборе значений придётся создавать новую перегрузку метода.
Так же не всегда однозначно хранение и передача куда-то кортежа.

Допустим, в метод приходит какой-то DTO.
Можно частично изменить его свойства и передать дальше для обработки.
С кортежем придётся для каждого изменения создавать новый экземпляр кортежа, так как это значимый тип.
И если его надо вернуть после обработки, то нужно или чтобы его метод возвращал, или параметр ref/out.

Но в целом, в реальных приложениях, там где раньше всегда использовался DTO сейчас в 99% проще заменить на кортеж или запись.

Есть ещё нюанс с объектами которые хранятся длительное время.
Если это DTO - то вы можете ему задать теги XML-документации и в любом месте использования быстро посмотреть справку по нему.
С кортежами это невозможно, поэтому описывать их приходится в тегах методов и др.членов их использующих.
Что часто очень не удобно.
Поэтому их следует делать "говорящими" - то есть имена в них должны быть очень просты в понимании на английском.

Добавлено через 10 минут
Для десяти параметров - лучше создать частично мутабельный DTO и передать его в методах параметра.
Что-то в таком духе:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
///<Summary>Класс параметров метода авторизации.</Summary>
public class AuthorizatArgs
{
    ///<Summary>Это логин.</Summary>
    public string Login {get;}
    ///<Summary>Это пароль.</Summary>
    public string Password {get;}
    ///<Summary>Это результат авторизации.</Summary>
    public bool IsAuthorizated {get; set;}
    ///<Summary>Это ошибка, если есть, авторизации.</Summary>
    public int Error {get; set;}
}
 
public void Authorizat(AuthorizatArgs args)
{
 
}
0
2 / 1 / 1
Регистрация: 17.11.2020
Сообщений: 105
11.02.2022, 21:59  [ТС]
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Что-то в таком духе:
Правильно я понимаю, что я могу DTO передать из VM в модель ? Потому что 10 параметров надо передавать из VM. К примеру пользователь заполнил 10 полей и их надо передать в модель для дальнейшей обработки и тд, я получается собираю 10 полей и отправляю в модель с параметром DTO (Authorizat(SignVM bla)), как написал вверху?

То что вы показали, это только для чтения, соотвественно я не смогу указать логин и пароль из VM, который ввел пользователь и получается DTO я могу так же в моделе делать?!
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16166 / 11286 / 2892
Регистрация: 21.04.2018
Сообщений: 33,175
Записей в блоге: 2
11.02.2022, 23:00
Цитата Сообщение от Ihave Посмотреть сообщение
Правильно я понимаю, что я могу DTO передать из VM в модель ?
DTO - это просто объект для передачи данных: Data Transfer Object.
Те же дефолтные .Net типы: int, double, string, Point и т.д. - тоже смело можно отнести к DTO.

Некую опасность могут нести только ссылочные мутабельные DTO.
Поэтому их обычно реализуют как значимые типы: int, double, кортежи.
Или как ссылочные иммутабельные: string, PropertyChangedEventArgs.
Но частично мутабельные тоже используются: RoutedEventArgs содержит одно мутабельное свойство Handled.
Так же изредка имеет смысл использование и полностью мутабельных ссылочных DTO: сущности в EF.
Ссылочные DTO сейчас легко строить на основе Записей.

Добавлено через 6 минут
Цитата Сообщение от Ihave Посмотреть сообщение
собираю 10 полей и отправляю в модель с параметром DTO (Authorizat(SignVM bla)), как написал вверху?
Да, всё верно.
Только надо не забывать, что Модель - это ОБЪЕКТ и даже почти всегда ЭКЗЕМПЛЯР.
Значит возможно какие-то данные передать заранее.
Допустим, при создании экземпляра Модели вы передаёте данные достаточные для создания соединения: адрес, порт, протокол и т.д.
При авторизации вам достаточно передать уже только логин и пароль, а данные для соединения уже не нужно передавать.
Если авторизация успешна, то авторизация фиксируется в Модели (допустим, ключ сеанса).
И для последующей передачи запроса, уже не нужно передавать ключ сеанса, достаточно передать только данные для запроса.

Добавлено через 1 минуту
Цитата Сообщение от Ihave Посмотреть сообщение
То что вы показали, это только для чтения, соответственно я не смогу указать логин и пароль из VM, который ввел пользователь и получается DTO я могу так же в модели делать?!
Поля и свойства "только для чтения" устанавливаются в конструкторе.
Я его просто не показал здесь, как само-мобой подразумевающееся и для уменьшения кода в посте.
2
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16166 / 11286 / 2892
Регистрация: 21.04.2018
Сообщений: 33,175
Записей в блоге: 2
12.02.2022, 11:12
Цитата Сообщение от Ihave Посмотреть сообщение
Я обновил проект на гитхабе
У вас реп кривой и из-за этого его трудно смотреть.
В нём много лишних файлов.
Вы, наверное, его создавали не в Студии, а "руками".
Поэтому в нём нет файла игнорирования.

Исправить не могу - поскольку нет прав.
Вам нужно:
1) Не входя в Студию очистить локальный реп от всех лишних файлов и папок. В вашем случае это: .vs, obj;
2) Синхронизировать реп, чтобы они удалились на Гите;
3) В корень локального репозитория добавить вот эти два файла из архива: filesForGit.7z;
4) Войти в Студию и синхронизировать из неё.

В будущем, советую для работы с Гитом для Решений Студии использовать только саму Студию, включая создание Репа на Гите.
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
12.02.2022, 11:12

Разбор JSON, используя Newtonsoft.Json
Добрый день! Подскажите пожалуйста, как десериализовать JSON-ответ следующего вида {&quot;result&quot;: ...

Моделирование работы РЛС с использованием объектно-ориентированного подхода
Товарищи,появился вопрос.Написал программу которая моделирует работу РЛС с декартовой системе координат с двумя координатами х и у.Но...

Использованием навигационного подхода без применения SQL запросов
Разработать клиентское приложение, которое должно содержать несколько вкладок. Каждая из вкладок предназначена для представления...

Моделирование работы РЛС с использованием объектно-ориентированного подхода
Задание: Требуется создать программу (консольное приложение), реализованную с помощью классов и предназначенную для моделирования процесса...

Парсинг json ответа api vk. Вложенность Json
Ответ в json response: { count: 6641, items: , post_source: { type: 'vk' }, comments: { count: 24,


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
40
Ответ Создать тему
Новые блоги и статьи
Беседа с ИИ о программистах, недопускающих к созданию и правке кода генеративные ИИ и причины этого
zorxor 21.09.2026
Раньше я радовался или получал некоторые эмоции, пусть небольшие, но всё же, от самого процесса написания кода, рекомпиляции и запуска, видя постепенное развитие программы и прочее. А теперь лень. . .
Мобильное приложение ColorStep
pavlinmavlin 17.09.2026
Реализовал приложение Красный, Зеленый, Синий в Unity3d + c#. Название изменил на ColorStep. Приложение прошло модерацию и теперь доступно для скачивания. Делал его сам, шаг за шагом — и вот,. . .
Запрет дублирования строк в табличной части
Maks 13.09.2026
Реализация из решения ниже выполнена на нетиповом справочнике "Нормы ТО" с табличной часть "Виды ТО", разработанного в КА2, со следующими реквизитами: - ВидТО (СправочникСсылка. ВидыТО); - ВидГСМ. . .
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр.
Jin X 06.09.2026
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр. Работая с форумом и нейросетями в браузере часто хочется что-то подкорректировать или добавить какого-то функционала. Ниже прикреплён. . .
Программа опроса у.з. расходомера SLS-720F
Argus19 02.09.2026
Программа опроса у. з. расходомера SLS-720F Программа опрашивает один раз в минуту три ультразвуковых расходомера SLS-720F через интерфейс RS-485 по протоколу Modbus RTU. Опрашиваются регистры. . .
Hyper-V: Компьютер должен поддерживать доверенный платформенный модуль 2.0.
Maks 31.08.2026
При установке Windows 11 на виртуальную машину Hyper-V 2-го поколения вылезла такая ошибка: Решение: в параметрах виртуальной машины, в разделе "Безопасность" (Security) активировать флаг. . .
Архитектура биовида Стива в Майнкрафте: Зачем бонобо кубический каннибализм
anaschu 30.08.2026
Кубический Вагинокапитализм в Minecraft: Математический инвариант ОДУ и рок Стивов-бонобо Главная задача разработанной «Модели Всего» — наглядно продемонстрировать наличие системной «судьбы». . .
Оттачиваю умение писать js программы.
russiannick 30.08.2026
Проектом выходного дня стало написание Книги шифров Виженера. Итогом стала версия 200, синий туман. Синий туман назван так, потому что замораживает текст под собой. Нажатие синих кнопок управляют. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru