• Как сделать так чтобы в input нельзя было вводить меньше 5?

    @awenn2015
    Веб-программист самоучка
    Можно через событие onBlur валидировать

    const Input = () => {
      const range = { min: 5, max: 50 }
      const [value, setValue] = useState<number | "">(range.min)
    
      function onBlurHandle(value: number) {
        if (value >= range.min && value < range.max) return;
        setValue(range.min)
      }
    
      return (
        <input
          type="number"
          value={value}
          onChange={({ target }) => setValue(target.value === "" ? "" : +target.value)}
          onBlur={({ target }) => onBlurHandle(+target.value)}
          min={range.min}
          max={range.max}
        />
      )
    }
    Ответ написан
    Комментировать
  • Как написать асинхронный запрос к local storage?

    zkrvndm
    @zkrvndm
    Архитектор решений
    Существует альтернатива для localStorage, речь о IndexedDB. Для него в свою очередь существует удобная обертка - localForage, где все вызовы как раз асинхронные, на промисах.

    Присмотритесь к нему, очень рекомендую:
    https://habr.com/ru/company/nordavind/blog/212709/
    https://html5.by/blog/localforage/
    Ответ написан
    Комментировать
  • Почему получаю False при сравнение 2-х одинаковых строк?

    WNeZRoS
    @WNeZRoS
    Всегда можно написать функцию для поиска разницы:
    (int, char, char) FindFirstDifference(string a, string b)
    {
        var length = Math.Min(a.Length, b.Length);
        for (int i = 0; i < length; i++) 
        {
            if (a[i] != b[i])
                return (i, a[i], b[i]);
        }
    
        if (a.Length == b.Length)
            return (-1, '\0', '\0');
    
        return (length, a.Length == length ? '\0' : a[length], b.Length == length ? '\0' : b[length]);
    }


    В теории могут быть визуально похожие unicode символы, но в вашем случае они просто разные.
    Ответ написан
    Комментировать
  • Post запрос к апи, как написать используя httpclient?

    using System.Net.Http;
    using System.Net.Http.Headers;
    using System.Text.Json;
    
    var request = new // По хорошему надо вынести в отдельный класс или record
    {
        sinceDateTimeUtc = new DateTime(2020, 01, 01, 0, 0, 0),
        tillDateTimeUtc = new DateTime(2022, 12, 11, 0, 0, 0),
    };
    
    var httpRequest = new HttpRequestMessage
    {
        Method = HttpMethod.Post,
        RequestUri = new Uri("https://test/test/test/sync?test&operation=test"),
        Headers = {
            Authorization = AuthenticationHeaderValue.Parse("1sav23456vdsa7vsa8"),
            Accept = {MediaTypeWithQualityHeaderValue.Parse("application/json")}
        },
        Content = new StringContent(JsonSerializer.Serialize(request))
        {
    
            Headers = {
              ContentType = MediaTypeHeaderValue.Parse("application/json"),
            },
        },
    };
    
    // По возможности httpClient нужно переиспользовать. Инициализируй 1 раз, сделай побольше запросов, а в конце Dispose()
    using var httpClient = new HttpClient(); 
    
    var response = await httpClient.SendAsync(httpRequest);
    // Дальше работаем с response так, как нам нужно
    var contentString = await response.Content.ReadAsStringAsync();
    Console.WriteLine(contentString);


    Если нужно спарсить ответ как json, то используй JsonSerializer.Deserialize нас пришедшем стриме.
    Ответ написан
    2 комментария
  • Как реализовать одновременное присваивание и ввод чисел через пробел?

    WNeZRoS
    @WNeZRoS
    Можно сделать так же как в Python:
    var (a, b) = Console.ReadLine().Split(" ").Select(int.Parse);


    но надо добавить метод деконструкции IEnumerable на 2 элемента:
    public static class DeconstructEnumerable
    {
    	public static void Deconstruct<T>(this System.Collections.Generic.IEnumerable<T> enumerable, out T item1, out T item2)
    	{
    		using var enumerator = enumerable.GetEnumerator();
    		if (!enumerator.MoveNext())
    			throw new ArgumentException("not enough values to unpack (expected 2, got 0)", nameof(enumerable));
    										
    		item1 = enumerator.Current;
    										
    		if (!enumerator.MoveNext())
    			throw new ArgumentException("not enough values to unpack (expected 2, got 1)", nameof(enumerable));
    		
    		item2 = enumerator.Current;
    		
    		if (enumerator.MoveNext())
    			throw new ArgumentException("too many values to unpack (expected 2)", nameof(enumerable));
    	}
    }
    Ответ написан
    1 комментарий
  • Как реализовать удалённую БД с подключением через C#?

    1. Лучше бы не давать прямой доступ к СУБД для клиентов.
    2. Раз уже решил, что ты будешь делать именно SQL запросы, то выбирай из реляционных СУБД, с какими умеешь работать. Желательно ещё определиться с тем, какие именно данные ты будешь хранить, и какие операции с ними будешь производить.
    3. Чтобы узнать, как сделать запрос - обращайся к документации конкретно той библиотеки, с помощью которой ты подключаешься к СУБД.

    Если нужно минимум абстракций, то есть ADO .NET и соответствующие библиотеки:
    Microsoft.Data.Sqlite для sqlite
    Pomelo что-то там для MySQL
    Npgsql для Postgresql
    Microsoft.Data.Sqlserver для mssql
    Ну и оракловая либа (не помню название) для оракла.

    Всё можно найти на nuget.org по ключевым словам.

    Если нужен более высокий уровень абстракции, то смотри на ORM-ки:
    Entity Framework Core или Dapper.
    Ответ написан
    2 комментария
  • Как делается администрирование на сайтах?

    yarosroman
    @yarosroman
    C# the best
    для админки еще полезно посмотреть, что такое Areas в ASP.Net
    Ответ написан
    4 комментария
  • Чат на SignalR / Websocket - как видеть в режиме реального времени, что печатает пользователь?

    @Levhav
    Возьмусь за разработку проектов любой сложности.
    Логичнее не после каждого символа, а с задержкой. По опыту реализации этой функции скажу что лучше если отправлять сообщение спустя примерно 300 мс после последнего вызова события keyup

    Не знаю как оно именно в SignalR но мне кажется можно не сохранять в бд а сразу отправлять пользователям чата. Так как не страшно если потеряется одно из этих сообщений так как скоро придёт следующее.
    Ответ написан
    Комментировать
  • Каким образом можно удостовериться, что пользователь закрыл вэб-страницу?

    Taraflex
    @Taraflex
    Ищу работу. Контакты в профиле.
    смотрю в сторону SignalR, но не слишком ли это

    Не слишком.
    ИМХО единственный надежный способ узнать когда отвалился клиент - поддерживать с ним постоянное websocket соединение.
    Установили соединение - залочили ресурс.
    Оборвалось - разлочили.
    Ответ написан
    Комментировать
  • Чат на ASP.NET Core + SignalR - как его подключить к другому сайту скриптом?

    DarkRaven
    @DarkRaven
    разработка программного обеспечения
    Фактически, вы делаете SaaS.
    Т.е., у вас должно быть:
    • Какая-то страница. которая выводит чат и зависит от каких-то параметров (имя участника и т.п.)
    • Скрипт, который может добавить на страницу iframe с нужными параметрами (все то же имя участника, id сайта - для безопасности, чтобы левые не могли юзать и т.п.), в котором будет открыта вышеназванная страница.

    Вот и все.
    Ответ написан
    Комментировать
  • Как увеличить надёжность SignalR?

    @shavakerzh
    .net developer
    Привет.
    SignalR нужен для доставки событий с сервера на клиент и не более.
    Описанные задачи можно решить, если хранить сообщения (в бд например).
    Ответ написан
    Комментировать
  • Как спланировать БД (чат)?

    zoonman
    @zoonman
    ⋆⋆⋆⋆⋆
    Итак, что вам нужно. Предполагается, что у вас есть табицы user и group.

    Таблица со списом чатов

    chat
    	id - идентификатор чата
    	name - название чата (тема обсуждения)
    	user_id - идентификатор  пользователя, который создал чат (необязательно)


    Список участников чата
    roster
    	chat_id - идентификатор чата
    	user_id - идентификатор пользователя
    	group_id - ид группы, если пользователь пишет от имени группы или NULL, если от пользователя (можно даже держать 2 записи, где group_id = null и где нет)


    Список сообщений
    messages
    	id - идентификатор сообщения
    	chat_id - идентификатор чата
    	user_id - ид пользователя
    	group_id - ид группы, если сообщение отправлено от имени группы или NULL, если от пользователя
    	text - текст сообщения


    Статусы сообщений
    message_status
    	message_id - идентификатор сообщения
    	user_id - идентификатор пользователя
    	read - прочтено или нет
    	notified - отправлено уведомление о сообщении или нет


    Итак, как это работает.
    Круг, в котором общаются пользователи называется чатом (chat).
    Кто находится в чате определяется через ростер (roster). Ростер может не быть показан в интерфейсе.
    Кто кого приглашает в чат определяется через бизнес-логику приложения.

    В данной схеме сценарий "Пользователь2 пишет в Группа1" выглядит так.
    Создается чат, далее в ростер добавляются П2 и Г1. Далее просто создается сообщение от имени П2. Через бизнес-логику находится владелец Г1 и ему отправляется уведомление.
    Ответ написан
    Комментировать