Форум программистов, компьютерный форум, киберфорум
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. Показов 9475. Ответов 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
19.02.2022, 20:54  [ТС]
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Я тоже обновил ответами на вопросы.
Посмотрите.
C#
1
2
        // REM: Нужен грамотный конвертор!
        // ANS: Для чего? Что он должен делать?
Показывать ошибка это или успешное завершение операции StatusCode.
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16166 / 11286 / 2892
Регистрация: 21.04.2018
Сообщений: 33,176
Записей в блоге: 2
19.02.2022, 20:55
Посмотрел
Уже что-то похожее на правду.

НО!!!
Теперь выясняется, что у вас есть состояние занятости - если я правильно понял.
Тогда нужно добавить его индикацию, взвод, сброс.

Добавлено через 1 минуту
Цитата Сообщение от Ihave Посмотреть сообщение
Показывать ошибка это или успешное завершение операции StatusCode.
Всё равно не понял.
Конвертер конвертирует одно значение в другое.
Что во что он должен конвертировать?
0
2 / 1 / 1
Регистрация: 17.11.2020
Сообщений: 105
19.02.2022, 21:04  [ТС]
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Конвертер конвертирует одно значение в другое.
Что во что он должен конвертировать?

StatusCode - 200 в состояние Success, которое поймет V. Так как 200 для InfoBar ничего не значит.

Цитата Сообщение от Элд Хасп Посмотреть сообщение
Теперь выясняется, что у вас есть состояние занятости - если я правильно понял.
Тогда нужно добавить его индикацию, взвод, сброс.
Снова мысли от ТЗ - Если можно так сказать, за первый заход по команде блокируется textblock и первая кнопка, если ответа 200, то появляется панель c смс, но панель с textblock остается заблокированной, для того чтобы данные не изменились и не сбилась смс, панель с смс снова обращается к той же самой команде с номером телефона и уже с введеной смс и получает токен или не получает, не получает токен, показывает ошибку, получает токен, обращается к проверке токена и переводит потом на новую страницу.

Я уже подумал, что можно в модели еще один возврат bool сделать на этот случай тогда, если нельзя в VM лишних свойств.
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16166 / 11286 / 2892
Регистрация: 21.04.2018
Сообщений: 33,176
Записей в блоге: 2
19.02.2022, 23:30
Цитата Сообщение от Ihave Посмотреть сообщение
StatusCode - 200 в состояние Success
То есть при поступление HttpStatusCode.OK задать InfoBarSev=InfoBarSeverity.Success?

В текущей реализации HttpStatusCode получает только метод MyExecute.
Пусть при получении проверяет его значение и устанавливает свойство InfoBarSev.

Или есть какие-то иные ограничения?

Цитата Сообщение от Ihave Посмотреть сообщение
Снова мысли от ТЗ - Если можно так сказать...
Совершенно не понятно.
Я откуда знаю что это за Textblock?
И как понять "заблокированный TextBlock"? Невидимый что ли?

Вы объясните действия логические, на человеческом языке.

Вводится логин, нажимается кнопка вход, отправляется запрос, приходить ответ .... ну. и т.д,

Я понимаю из ваших объяснений, что это какой-то протокол двойной авторизации через sms, но деталей понять не могу.

Напишу как понял:
1) Ввод логина;
2) Клик аторизации;
3) блокировка поля ввода логина от изменений и запрос с указанным логином;
4) Может прийти два типа ответов;
5) Первый тип: Всё Ок - авторизация успешна;
6) Второй тип: нужен код из смс;
7) Показывается доп. поле для ввода кода;
8) После ввода - повторная авторизация с тем же логином и кодом.
0
2 / 1 / 1
Регистрация: 17.11.2020
Сообщений: 105
20.02.2022, 00:11  [ТС]
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Пусть при получении проверяет его значение и устанавливает свойство InfoBarSev.
Или есть какие-то иные ограничения?
писал об этом: 90
Но нужен грамотный конвертор, так как ошибка
Cannot directly bind type 'ViewModel.SignVM+InfoBarSeverity' to 'Microsoft.UI.Xaml.Controls.InfoBarSever ity'. Use a cast, converter or function binding to change the type

Цитата Сообщение от Элд Хасп Посмотреть сообщение
Я понимаю из ваших объяснений, что это какой-то протокол двойной авторизации через sms, но деталей понять не могу.
Поняли вы все верно. Вот дополнительные подробности:
1) Поле с вводом номера телефона;
2) Кнопка "войти" со свойством клика авторизации;
3) Блокировка поля с номером телефона и кнопки войти - запрос (клик авторизации) с указанным номером телефоном
5) Может прийти два типа ответов;
a) Ответ 200: - показывается доп поле для ввода кода смс. Поле с номером телефона и кнопкой авторизацией остаются заблокированы. Появлятеся infobar с Success
b) Другие ответы не 200: появляется infobar с ошибкой. Разблокируется поле номера телефона и кнопки войти
6) Ввод кода смс - запрос (клик авторизации) с указанным номером телефона и кодом смс !
7) Может прийти два типа ответов:
a) Ответ 200: - получаем токен. идет запрос чек токен, а после запроса уже открывается страница MainPage и тд....
b) Другие ответы не 200: появляется infobar с ошибкой.

Блокированый - IsEnabled="false"
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16166 / 11286 / 2892
Регистрация: 21.04.2018
Сообщений: 33,176
Записей в блоге: 2
20.02.2022, 09:26
Цитата Сообщение от Ihave Посмотреть сообщение
писал об этом: 90
.....
Цитата Сообщение от Ihave Посмотреть сообщение
Cannot directly bind type 'ViewModel.SignVM+InfoBarSeverity' to 'Microsoft.UI.Xaml.Controls.InfoBarSever ity'. Use a cast, converter or function binding to change the type
Не конвертер.
У писал уже не раз (не помню вам тоже или нет) в современном Шарпе не используются вложенные публичные типы.
А WPF с ними, вообще, плохо работает.
У думал вы просто для примера показали перечисление InfoBarSeverity внутри VM.
Вынесите его в пространство имён и в отдельный файл.

Добавлено через 3 минуты
И второе.
Я не пойму для чего вам это перечисление.
Вам нужно перечисление Microsoft.UI.Xaml.Controls.InfoBarSeveri ty или ваше собственное?

Может вы собственное привели для примера, а нужно вам преобразовывать HttpStatusCode в Microsoft.UI.Xaml.Controls.InfoBarSeveri ty?

Добавлено через 23 минуты
Ihave, если правильно понял, то вот такой конвертер:
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
using Microsoft.UI.Xaml.Controls;
using System;
using System.ComponentModel;
using System.Net;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Data;
 
namespace Converters
{
    public class HttpStatusCodeToInfoBarSeverityConverter : IValueConverter
    {
        private static readonly EnumConverter enumConverter = new EnumConverter(typeof(HttpStatusCode));
        public object Convert(object value, Type targetType, object parameter, string language)
        {
            if (enumConverter.IsValid(value))
            {
                HttpStatusCode code = (HttpStatusCode)enumConverter.ConvertFrom(value);
 
                // Возврат нужных значений
                switch (code)
                {
                    // Например
                    case HttpStatusCode.Accepted: return InfoBarSeverity.Success;
                }
            }
 
            // Неопределённое значение, если на вход поступило не конвертируемое значение
            return DependencyProperty.UnsetValue;
        }
 
        public object ConvertBack(object value, Type targetType, object parameter, string language)
        {
            throw new NotImplementedException();
        }
    }
}
Зафиксировал его на Гите.

Добавлено через 11 минут
Цитата Сообщение от Ihave Посмотреть сообщение
Поняли вы все верно. Вот дополнительные подробности:
Если я правильно понял, то Модель будет работать только с одним акком (логин - номер телефона) и одновременно она может отправлять только один запрос?

Если да, то:
1) Модель будет иметь состояния: не авторизирована, авторизация начата, треба код смс для продолжения авторизации, авторизация успешно завершена, ошибка авторизации. Надо эти состояния раскидать по одному-двум свойствам;
2) У Модели должен быть флаг занятости: приняла запрос - подняла флаг; обработала запрос и перед его возвратом - сбросила флаг. Это тоже отдельное свойство;
3) Идентификатор текущего акка (номер телефона) - отдельное свойство;
4) Эти состояния должны отражаться в свойства VM;
5) Для уведомления об изменении состояния Модель должна подымать событие (или события). Пока для упрощения можно для этого использовать реализацию INPC.
0
2 / 1 / 1
Регистрация: 17.11.2020
Сообщений: 105
20.02.2022, 15:01  [ТС]
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Может вы собственное привели для примера, а нужно вам преобразовывать HttpStatusCode в Microsoft.UI.Xaml.Controls.InfoBarSeveri ty?
Да, я привел его для примера и пробывал варианты.

Цитата Сообщение от Элд Хасп Посмотреть сообщение
если правильно понял, то вот такой конвертер:
Вы правиряли конвертор ? У меня вызывает ошибку: EnumConverter cannot convert from System.Net.HttpStatusCode или я что-то не так делаю.


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

Поэтому вот что я придумал, а вы поправьте если это не верно.
1) Я дополнительно на первый запрос только с номером телефона будут возвращать bool из модели в VM, который и будет отвечать за блокировку поля с номером телефона.

Добавлено через 20 минут
Цитата Сообщение от Ihave Посмотреть сообщение
Вы правиряли конвертор ? У меня вызывает ошибку: EnumConverter cannot convert from System.Net.HttpStatusCode или я что-то не так делаю.
Вообщем переделал ваш конвертор и теперь все работает:

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
namespace Converters
{
    public class HttpStatusCodeToInfoBarSeverityConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, string language)
        {
 
            if (!value.GetType().Equals(typeof(HttpStatusCode)))
            {
                throw new ArgumentException("Only HttpStatusCode is supported");
            }
            if (targetType.Equals(typeof(InfoBarSeverity)))
            {
 
                if((HttpStatusCode)value == HttpStatusCode.OK)
                {
                    return InfoBarSeverity.Success;
                }
 
                else
                {
                    return InfoBarSeverity.Error;
                }
                
            }
            else
            {
                throw new ArgumentException("Unsuported type {0}", targetType.FullName);
            }
        }
 
        public object ConvertBack(object value, Type targetType, object parameter, string language)
        {
            throw new NotImplementedException();
        }
    }
}
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16166 / 11286 / 2892
Регистрация: 21.04.2018
Сообщений: 33,176
Записей в блоге: 2
20.02.2022, 18:02
Цитата Сообщение от Ihave Посмотреть сообщение
Вы правиряли конвертор ?
Нет.
Не было времени.
Только освободился.
Делал как в WPF.
Может в UWP есть свои нюансы.

Цитата Сообщение от Ihave Посмотреть сообщение
Вообщем переделал ваш конвертор и теперь все работает:
Лучше использовать дефолтный конвертер.
ОН будет конвертировать и из совместимых типов.
Сейчас посмотрю что с ним не так.

Добавлено через 1 час 6 минут
Ihave, проверил - здесь немного по иному работает конвертер и ещё x:Bind тоже имеет свои нюансы.
Вот отлаженный вариант:
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
using Microsoft.UI.Xaml.Controls;
using System;
using System.ComponentModel;
using System.Net;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Markup;
 
namespace Converters
{
    public class HttpStatusCodeToInfoBarSeverityConverter : IValueConverter
    {
        private static readonly EnumConverter enumConverter = new EnumConverter(typeof(HttpStatusCode));
        public object Convert(object value, Type targetType, object parameter, string language)
        {
            if (enumConverter.IsValid(value))
            {
                if (!(value is HttpStatusCode code))
                    code = (HttpStatusCode)enumConverter.ConvertFrom(value);
 
                InfoBarSeverity ret;
                // Возврат нужных значений
                if (code == HttpStatusCode.OK)
                {
                    ret = InfoBarSeverity.Success;
                }
 
                else
                {
                    ret = InfoBarSeverity.Error;
                }
 
                if (typeof(string) == targetType)
                    return ret.ToString();
                return ret;
            }
 
            // Неопределённое значение, если на вход поступило не конвертируемое значение
            return DependencyProperty.UnsetValue;
        }
 
        public object ConvertBack(object value, Type targetType, object parameter, string language)
        {
            throw new NotImplementedException();
        }
 
        public static HttpStatusCodeToInfoBarSeverityConverter Instance { get; } = new HttpStatusCodeToInfoBarSeverityConverter();
    }
 
    public class HttpStatusCodeToInfoBarSeverityExtension : MarkupExtension
    {
        protected override object ProvideValue()
        {
            return HttpStatusCodeToInfoBarSeverityConverter.Instance;
        }
    }
}
Сделал фиксацию с ттестом.

Добавлено через 1 минуту
Очень странно работают в UWP конвертеры.
Я же проверяю сначала валидность значения методом IsValid(...) и тем не менее он потом выкидывает исключение.

Добавлено через 53 секунды
Проверял конвертацию из перечисления и из строки:
C#
32
33
34
35
36
        public class Example
        {
            public HttpStatusCode Code { get; } = HttpStatusCode.Accepted;
            public string Text { get; } = HttpStatusCode.OK.ToString();
        }
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16166 / 11286 / 2892
Регистрация: 21.04.2018
Сообщений: 33,176
Записей в блоге: 2
20.02.2022, 18:04
Цитата Сообщение от Ihave Посмотреть сообщение
Возможно я вас не правильно понял, но нет, модель будет одновременно работать как с логин - номер телефона так и с смс кодом
Да, вы неверно меня поняли.
Одновременно же только один логин может быть авторизирован?
При авторизации другого, авторизация первого закрывается.
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16166 / 11286 / 2892
Регистрация: 21.04.2018
Сообщений: 33,176
Записей в блоге: 2
20.02.2022, 18:09
Цитата Сообщение от Ihave Посмотреть сообщение
1) Я дополнительно на первый запрос только с номером телефона будут возвращать bool из модели в VM, который и будет отвечать за блокировку поля с номером телефона.
Неа.
Это разные состояния Модели: первичная авторизация и авторизация с кодом.
Соответственно в Модели нужно как-то показать в каком она состоянии.

Это принципы ООП.
Каждый метод делает только одну функцию.

Что-то в таком духе должно быть:
Вы смотрите состояние Модели - она готова к авторизации.
Послали запрос на авторизацию - ей состояние изменилось на "авторизация начата - требуется код".
Послали второй запрос на авторизацию - состояние изменилось "авторизация успешна" или "в авторизации отказано".
0
2 / 1 / 1
Регистрация: 17.11.2020
Сообщений: 105
20.02.2022, 18:35  [ТС]
Цитата Сообщение от Элд Хасп Посмотреть сообщение
проверил - здесь немного по иному работает конвертер и ещё x:Bind тоже имеет свои нюансы.
Вот отлаженный вариант:
У меня все равно вызывал исключение... Пока заменил на тот который работает.

Цитата Сообщение от Элд Хасп Посмотреть сообщение
Одновременно же только один логин может быть авторизирован?
При авторизации другого, авторизация первого закрывается.
Что значит закрывается ? Там же проверки идут, нету поле для смс, значит спокойно пробуешь номер телефона вводить, как только номер телефона подвержден и выслана смс, появляется панель с смс, но панель с телефоном заблокирована, вводишь смс, не правильно вводишь 3 смс - блокируется на время аккаунт. И Все это в один метод.


Цитата Сообщение от Элд Хасп Посмотреть сообщение
Неа.
Это разные состояния Модели: первичная авторизация и авторизация с кодом.
Соответственно в Модели нужно как-то показать в каком она состоянии.
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Что-то в таком духе должно быть:
Вы смотрите состояние Модели - она готова к авторизации.
Послали запрос на авторизацию - ей состояние изменилось на "авторизация начата - требуется код".
Послали второй запрос на авторизацию - состояние изменилось "авторизация успешна" или "в авторизации отказано".
Звучит классно, но я пока сделал с возвратом bool SuccessSms и отыгрываю этот bool, посмотрите как будет время полностью SignVM и SignM.


Еще вопрос по поводу "красоты"
Это пример:
C#
1
2
3
4
5
6
7
8
9
10
11
12
        
private void LoginKeyUp_Enter(object sender, KeyRoutedEventArgs e)
        {
            if (e.Key == VirtualKey.Enter)
            {
                if (SignViewModel.SetPhone != null)
                {
                    SignViewModel.MyCommandPhone.Execute(null);
                }
 
            }
        }
Хотелось бы, что когда пользователь ввел номер и нажал Enter, у него пошел клик или вызов команды, данный пример рабочий, НО проблема в следующем, что SetPhone через биндинг сохраняет свое состояние после того, как ты уберешь от него "ФОКУС".

Ввел номер телефона жмешь Enter вызывается клик или команда и SetPhone оказывается пустым, возвращается ошибка, что SetPhone пустой
Получается следующие: Если ввести номер и убрать фокус с бокса номера телефона, а потом снова перевести фокус на ввод номера телефона и нажать Enter, то в поле SetPhone были сохранены данные.

Как можно сохранять данные в SetPhone в процессе ввода данных ?

PS Обновил реп 8852723
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16166 / 11286 / 2892
Регистрация: 21.04.2018
Сообщений: 33,176
Записей в блоге: 2
20.02.2022, 18:47
Цитата Сообщение от Ihave Посмотреть сообщение
У меня все равно вызывал исключение... Пока заменил на тот который работает.
Я же рабочую фиксацию скинул.
Зафиксируйте вариант использования при котором выдаёт исключение.

Добавлено через 1 минуту
Цитата Сообщение от Ihave Посмотреть сообщение
Что значит закрывается ?
Вы авторизовались с номера 111111.
Теперь вам захотелось авторизоваться с номера 999999.
Ваше приложение должно ОДНОВРЕМЕННО работать с двумя номерами.
Или для авторизации по 999999 надо выйти из 111111 ?
0
2 / 1 / 1
Регистрация: 17.11.2020
Сообщений: 105
20.02.2022, 18:51  [ТС]
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Или для авторизации по 999999 надо выйти из 111111 ?
Ну да, авторизация только чтобы получить токен и выполняется один раз! Потом используется токен, если есть токен, будет игнорироваться все время страница с авторизацией, будет открываться сразу же главная страница приложения уже с данными. Если пользователь хочет зайти с 99999, он выходит из приложения (удаляется токен) и попадает на страницу с авторизацией, где снова получит токен, только уже на номер 99999.
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Я же рабочую фиксацию скинул.
Зафиксируйте вариант использования при котором выдаёт исключение.
Выкидывал общую ошибку App... Но я попробую пошаманить с вашим вариантом еще.
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16166 / 11286 / 2892
Регистрация: 21.04.2018
Сообщений: 33,176
Записей в блоге: 2
20.02.2022, 19:14
Цитата Сообщение от Ihave Посмотреть сообщение
Выкидывал общую ошибку App... Но я попробую пошаманить с вашим вариантом еще.
Понял в чём дело.
x:Bind не принимает DependencyProperty.UnSet.
А у вас там некорректное значение поступает вначале.
Фиксацю отправил.

Добавлено через 1 минуту
Цитата Сообщение от Ihave Посмотреть сообщение
Ну да, авторизация....
ВОТ! Об этом я и говорю.
Логин - это часть состояния Модели. Самое простое, после начала авторизации, его зафиксировать в свойстве Модели.

Вы ни как не можете мыслить без UI.
Все ваши идеи, предложения начинаются с UI и заканчиваются на нём.
UI - это третьестепенная часть Приложения.
А VM, вообще, где-то на 10 уровне.
1
2 / 1 / 1
Регистрация: 17.11.2020
Сообщений: 105
20.02.2022, 19:15  [ТС]
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Понял в чём дело.
x:Bind не принимает DependencyProperty.UnSet.
А у вас там некорректное значение поступает вначале.
Фиксацю отправил.

Хорошо, сейчас проверю

Цитата Сообщение от Элд Хасп Посмотреть сообщение
ВОТ! Об этом я и говорю.
Логин - это часть состояния Модели. Самое простое, после начала авторизации, его зафиксировать в свойстве Модели.
Можете показать на примере ? Не совсем понимаю, как вы хотите реализовать.
0
2 / 1 / 1
Регистрация: 17.11.2020
Сообщений: 105
20.02.2022, 19:22  [ТС]
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Вы ни как не можете мыслить без UI.
Все ваши идеи, предложения начинаются с UI и заканчиваются на нём.
UI - это третьестепенная часть Приложения.
А VM, вообще, где-то на 10 уровне.
Это вы к чему написали?


Цитата Сообщение от Элд Хасп Посмотреть сообщение
Фиксацю отправил.
Все работает. Спасибо
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16166 / 11286 / 2892
Регистрация: 21.04.2018
Сообщений: 33,176
Записей в блоге: 2
20.02.2022, 19:25
Цитата Сообщение от Ihave Посмотреть сообщение
Это вы к чему написали?
Оторвалось от предыдущего поста.
Сейчас приклею - а то связь потерялась.
0
2 / 1 / 1
Регистрация: 17.11.2020
Сообщений: 105
20.02.2022, 19:38  [ТС]
Цитата Сообщение от Элд Хасп Посмотреть сообщение
ВОТ! Об этом я и говорю.
Логин - это часть состояния Модели. Самое простое, после начала авторизации, его зафиксировать в свойстве Модели.
Вы ни как не можете мыслить без UI.
Все ваши идеи, предложения начинаются с UI и заканчиваются на нём.
UI - это третьестепенная часть Приложения.
А VM, вообще, где-то на 10 уровне.
Это не мысли только от UI, это факт, в котором общаться с WEB сервером можно только по жеско определеным правилам.
Так же я пишу от UI, чтобы просто обьяснить суть. Я понимаю, что нужно исходить от модели и VM должно быть только отражение модели, некоторые вещи просто делаю, так как могу, в силу не знаний MVVM. Отсюда и проблемы.

Что значит зафиксировать в свойстве модели ? Зачем? для чего ? Чтобы что потом с ним делать ? Если будет у вас время, покажите, как должно это выглядить на реальном примере. А то я так не понимаю, что вы имеете ввиду и соотвественно, что я должен сделать.
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16166 / 11286 / 2892
Регистрация: 21.04.2018
Сообщений: 33,176
Записей в блоге: 2
20.02.2022, 19:56
Цитата Сообщение от Ihave Посмотреть сообщение
Можете показать на примере ? Не совсем понимаю, как вы хотите реализовать.
Накидываю здесь.
Поэтому только логика без деталей.
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
class SignM
{
    public string Login {get; private set;}
    public bool IsBusy {get; private set;}
    public bool IsAuthorization  {get; private set;}
    public bool CodeRequired  {get; private set;}
    public bool AuthorizationDenied {get; private set;}
 
    public ... Authorize(string login)
    {
        if(IsBusy)
           throw ....;
        IsBusy = true;
 
        Login = string.Empty;
        IsAuthorization = false;
        CodeRequired = false;
        AuthorizationDenied = false;
        
        // Дальше запрос и его обработка
 
        if(/* Если успешно */)
        {
            Login = login;
            IsAuthorization  = true;
        }
        else if (/* Если требуется код */)
        {
            Login = login;
            CodeRequired  = true;
        }
        else /* Если не успешно */
        {
            Login = login;
            AuthorizationDenied = true;
        }
 
        // Продолжение кода
 
        IsBusy = false;
     }
 
    public ... Authorize(string login, string code)
    {
        if(IsBusy)
           throw ....;
        IsBusy = true;
 
        if (login != Login)
        {
             // исключение или сообщение о неверном логине
        }
        else if (IsAuthorization)
        {
            // Сообщение, что авторизация уже проведена
        }
        else if (!CodeRequired)
        {
            // Сообщение что код не был затребован
        }
 
       
        // Дальше запрос и его обработка
 
        if(/* Если успешно */)
        {
            IsAuthorization  = true;
            CodeRequired = false;
        }
        else /* Если не успешно */
        {
            AuthorizationDenied = true;
        }
 
        // Продолжение кода
 
        IsBusy = false;
      }
}
Добавлено через 6 минут
Цитата Сообщение от Ihave Посмотреть сообщение
Зачем? для чего ?
Модель существует сама по себе.
К ней может быть подключена одна VM, может 100 VM, а может ни одной.
И каждая VM отражает состояние Модели.
А если вы будет это состояние хранить только в VM (по возвращённому методом значению), то другая VM не будет знать об этом и ,соответственно, не сможет правильно отразить состояние Модели.

Представьте, что на каждое действие вы создаёте новую VM.
Как вторая VM узнает, что авторизация уже начата другой VM и сейчас надо отправить код?

Добавлено через 3 минуты
Ведь по сути View с вводом логина, и View в котором логин уже есть и вводится код - это две РАЗНЫЕ View.
Вы просто их совместили в одном XAML.
Так же у каждой из них своя VM, которые вы тоже совместили в одной.
А VM НЕ ДОЛЖНЫ ХРАНИТЬ ДАННЫЕ.
Если бы вы их раздели функционально, то вам самому это стало бы очевидно.
0
2 / 1 / 1
Регистрация: 17.11.2020
Сообщений: 105
20.02.2022, 20:08  [ТС]
Цитата Сообщение от Элд Хасп Посмотреть сообщение
К ней может быть подключена одна VM, может 100 VM, а может ни одной.
И каждая VM отражает состояние Модели.
А если вы будет это состояние хранить только в VM (по возвращённому методом значению), то другая VM не будет знать об этом и ,соответственно, не сможет правильно отразить состояние Модели.
Представьте, что на каждое действие вы создаёте новую VM.
Как вторая VM узнает, что авторизация уже начата другой VM и сейчас надо отправить код?
Так вот поэтому у меня и дессонанц, не нужно, чтобы другая VM знала, не нужно чтобы обращалась другая VM или еще что, там идет все строго и очень строго в иерархии, нету одновременно разных запросов, запрос - ответ, запрос - ответ. У каждой VM свой запрос и только свой уникальный ответ от модели. Я имею ввиду только вход, мы его разбираем сейчас.

Ещё раз в модели у нас вот такой метод:
C#
1
        public (bool isAuthorizated, bool SuccessSms, string error, HttpStatusCode StatusCode) Authorizat(string SetPhone, string SetSms)
Этот метод отвечает за отражение в SignVM, она одна и только одна и прикреплена только и будет только к SignVM

На другие отражение VM, я буду создавать новые методы в Модели по типу той, что наверху. Как например. Я создал:

C#
1
        public (bool IsNews, HttpStatusCode StatusCode, RootNews responsesign) GetNews(PostNews setData)
Этот метод отвечает за отражение в NewsVM, она одна и только одна и прикреплена только и будет только к NewsVM и тд

Это правильная логика MVVM ? Или вы имеете ввиду, что здесь ошибка ?

Добавлено через 4 минуты
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Ведь по сути View с вводом логина, и View в котором логин уже есть и вводится код - это две РАЗНЫЕ View.
Вы просто их совместили в одном XAML.
Так же у каждой из них своя VM, которые вы тоже совместили в одной.
А VM НЕ ДОЛЖНЫ ХРАНИТЬ ДАННЫЕ.
Если бы вы их раздели функционально, то вам самому это стало бы очевидно
Почему это разные View ? Просто на каждом этапе вводятся определеные данные.
VM не должна хранить данные ? Это как понимать ? Она по сути хранит, то что в нее ввели? Или нет ?

Данные потом все равно надо совмещать в один, при разделение их, надо в финале передавать так же логин и код, если вы разделите логику, нужно будет все равно логин передавать, так как второй запрос требует одновременно и логина и кода. А при первом только логиню.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
20.02.2022, 20:08

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

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

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

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

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


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

Или воспользуйтесь поиском по форуму:
120
Ответ Создать тему
Новые блоги и статьи
Nekobox - outbounds[0].transport: unknown transport type: raw
damix 01.10.2026
Фикс ошибки Правым кликом по серверу -> отладочная информация -> edit Заменить "net": "raw", на "net": "tcp", Нажать кнопку reload.
Программный домашний кинотеатр
russiannick 27.09.2026
Сподобился на программный домашний кинотеатр. В качестве ЯВУ по традиции выбрал js. В помощники взял Яндекс-Алису. Было создано три зала на разные интересы. исторические и ретро сериал Хичкок. . .
Беседа с ИИ о программистах, недопускающих к созданию и правке кода генеративные ИИ и причины этого
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) активировать флаг. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru