Задать вопрос
Ответы пользователя по тегу .NET
  • Можно ли использовать Expression без типов-делегатов?

    @mvv-rus
    Настоящий админ AD и ненастоящий программист
    Вкратце: не заморачивайтесь.
    В ремесле программирования есть полезный принцип, обозначаемый англоязычным сокращением YAGNI, что в переводе означает "Вам это не понадобится." Согласно этому принципу, раз вы не знаете, как можно использовать Expression с параметром-типом не являющимся делегатом, то вам вряд ли понадобится его так использовать.
    А проверки параметра-типа там нет, скорее всего, потому что эта функциональность (она называется Expression trees) появилось давно, больше 15 лет назад, в .NET Framework 3.5, а тогда в .NET проверки параметра-типа ЕМНИП не было.
    Но, подозреваю, что попытка использовать в качестве TDelegate не тип-делегат просто приведет к ошибке: почти наверняка - при попытке получить исполняемый код из выражения (метод Compile), а, возможно, и раньше - или при попытке создания объекта, или даже на этапе написания кода или компиляции: ее может (да или нет - не проверял) обнаружить анализатор при компиляции исходного кода и даже IntelliSense. И подозреваю, что при попытке обойти дерво такого объекта Expression tree (это - альтернативный способ использования этой функциональности), тоже будет ошибка - ибо выражение получается бессмысленным.
    В любом случае, истиной в последней инстанции является исходный код. Если вам так уж захотелось узнать, что будет - читайте исходный код: он лежит на GitHub, ссылка есть в документации по классу в learn.microsoft.com (сразу предупреждаю: там все сложно).
    Ответ написан
    Комментировать
  • Как в C# на этапе AddCookie[options.Events.OnValidatePrincipal] проверять активность сессии пользователя в стороннем auth-server?

    @mvv-rus
    Настоящий админ AD и ненастоящий программист
    Подскажите, как делают refresh_token взрослые дяди в многопоточке.

    Если нужен ответ на это конкретный вопрос, причем если имеется в виду не просто многопоточка, а асинхронная, с await без блокировки потока - то на это есть такой SemaphoreSlim. Делается примерно так (надеюсь, идея будет понятна)
    //Попадаем сюда после получения существующего access token и выявления, что он просрочен
        SemaphoreSlim sem = GetSemaphore(clientId); 
       await sem.WaitAsync(); //timeot и CancellationToken добавить по вкусу
       try {
         //Получаем существующий access token повторно - вдруг его уже кто-нибудь до нас обновил 
        //   (используем double check pattern)
        //Если это не так,  выполняем тут всю логику обновления access token
      }
      finally {
          sem.Release(); //SemaphoreSlim - не мьютекс, сам не освободится в случае чего
      }


    GetSemaphore реализовать можно по-разному. Можно один на все приложение: static или Singleton - это если нагрузка небольшая.
    А можно кэшировать семафоры по одному для каждого пользователя (т.е. свой семафор для каждого clientID), чтобы пользователи не толклись около одного семафора на всех.
    Главное, чтобы этот семафор создавался с начальным значением 1 - тогда он будет пускать пользователей по одному.

    Ну, а если все делать без асинхронности, в одном потоке, блокируя его при необходимости (т.е. без await), то способов много. Простейший - блок lock вокруг кода обновления маркера доступа (access token), есть такде Monitor, Mutex, тот же Semaphore (хоть со Slim, хоть без)...
    Ответ написан
    1 комментарий
  • Как реализовать TcpLister, который будет ожидать запроса?

    @mvv-rus
    Настоящий админ AD и ненастоящий программист
    Зависит от того, чего вы хотите.
    Если вас устраивает, что задача, выполняющая HandleClientAsync для подключившегося клиента будет брошена на произвол судьбы, можно использовать оба варианта (но первый мне нравится больше). Если вы хотите узнать, чем она закончилась - надо делать по-друому.
    PS См. также комментарии к вопросу.
    Ответ написан
    Комментировать
  • Как сделать общий appsettings.json для разных .sol?

    @mvv-rus
    Настоящий админ AD и ненастоящий программист
    Можно добавить произвольные файлы JSON в конфигурацию на этапе конфигурирования приложения. Используйте для этого метод расширения AddJsonFile интерфейса IConfigurationBuilder.
    В приложениях на современном (.NET 6+) шаблоне WebApplication этот интерфейс доступен через свойство WebApplicationBuilder.Configuration, примерно так:
    var builder = WebApplication.CreateBuilder(args);
    //...
    builder.Configuration.AddJsonFile("path_and_file.json");
    Ответ написан
    1 комментарий
  • Как написать свой кастомный EditorFor и получить значение свойства модели?

    @mvv-rus
    Настоящий админ AD и ненастоящий программист
    У вас в поле _helper класса FormHelper<TModel> конструктор сохраняет ссылку на интерфейс IHtmlHelper<TModel>.
    Этот интерфейс содержит свойство ViewData типа ViewDataDictionary<TModel>. А в этом типе реализовано свойство Model (типа TModel), которое даст вам ссылку на экземпляр класса (типа TModel) модели для представления/страницы.
    Ну, а дальше, раз вы знаете имя нужного вам свойства объекта и имеете ссылку на экземпляр этого объекта, то можете получить значение этого свойства: либо через составление с последующей компиляцией и вычисление выражения, возвращающего его значение, либо через отражение.
    Как-то так.
    Ответ написан
    1 комментарий
  • Как удалить сессию из БД после истечения срока?

    @mvv-rus
    Настоящий админ AD и ненастоящий программист
    В ASP.NET Core есть стандартный механизм сеансов (ISession): https://learn.microsoft.com/aspnet/core/fundamenta...
    Работает он на базе распределенного кэша (IDistributedCache), который штатными средствами можно базировать на MS SQL и на Redis (и, возможно, есть дополнительные сторонние пакеты для базирования на других СУБД,). Идентифкатор сессии хранится в куки (настраеваемой), по умолчанию - HTTP-only (но это настраивается).
    Механизм устаревания сеансов там есть, параметры тоже можно настроить.
    Кароче, если нет причин обязательно делать свой велосипед (типа, для учебной задачи) можно использовать этот стандартный механизм.
    Правда идея использовать этот механизм именно для авторизации у меня вызывает некоторые неясные опасения: он, вообще-то, не для того сделан. А именно для авторизации (плюс аутентифкация) в ASP.NET Core тоже есть штатное решение (Identity и политики авторизации). И вообще, аутентифкация/авторизация - это такое место, где легко накосячить, а потому лучше там обходиться без своих велосипедов.
    Ответ написан
    3 комментария
  • Как отсортировать вложенные друг в друга объекты?

    @mvv-rus
    Настоящий админ AD и ненастоящий программист
    Судя по вашему сегодняшнему вопросу, в котором вы пытаетесь решать эту задачу дальне вам нужно сделать эту работу на уровне БД.
    Если так, то для этого многие (хоть и не все, но, к примеру, в MS SQL Server и в PostgreSQL она AFAIK есть) СУБД имеют функциональность reursive CTE.
    Попробуйте поискать решение в этом направлении.
    Ответ написан
    Комментировать
  • Как реализовать атомарное обновление 2 файлов?

    @mvv-rus
    Настоящий админ AD и ненастоящий программист
    Движок ESE от Microsoft (его используют системные БД MS Windows и MS Exchange) на для уменьшения объема просматриваемого журнала транзакций ("лога", он там хранится не в одном большом файле а в куче мелких) при рестарте создает и обновляет отдельный файл контрольной точки, в котором сохраняется ссылка на транзакцию, до которой все точно зафиксировано. А при рестарте - запускает применение журнала транзакций с контрольной точки.
    Попробуйте подумать в эту сторону - может, подойдет.
    PS А еще в Windows, в файловой системе NTFS есть встроенная поддержка транзакционного обновления. Но, во-первых - это только в Windows, а во-вторых, я не помню, чтобы в .NET была библиотека для использования этой возможности, так что, не исключено, что доступаться до нее придется через P/Invoke
    Ответ написан
    Комментировать
  • Есть ли смысл завершать задачи генерируя ошибку(token.ThrowIfCancellationRequested()) если есть спобос получше?

    @mvv-rus
    Настоящий админ AD и ненастоящий программист
    Во-первых, ваш заголовок вводит в заплуждение: в нем - про завершение процесса, а справшиваете вы про завешение задачи.
    Во-вторых, задача может завершаться переходом в разные конечные состояния (они фиксируются в поле Task.Status). По оператору Return задача переходит в состояние RanToCompletion, по ThrowIfCancelationRequested - Canceled. Это - два логически разных состояния завершения (есть еще и третье - завершение по необработанному исключению, Faulted). Если коду, создаывшему задачу, совсем без разницы, как именно завершилась задача и вообще, завершилась ли она, то можете делать как угодно.
    Но, очень часто код, связанной с задачей,к примеру, операция await для задачи, ведет себя по-разному, в зависимости от состояния завершения задачи, получение результата задачи - тоже. А для задачи продолжения можно задать условия, при каком состоянии завершения предыдущей задачи эта задача продолжения будет запущена. То есть, состояние завершения задачи обычно имеет значение.
    Ответ написан
    Комментировать
  • Почему надо явно добавлять пакет Microsoft.NET.Test.Sdk в гл проект, если в одном из пакетов он уже есть?

    @mvv-rus
    Настоящий админ AD и ненастоящий программист
    Так нужно, потому что ссылки не транзитивны. Средства разработки не могут взять метаданные (описания сборок, классов и т.д.), которые нужны для работы и компилятора, и других средств разработки (IDE, в частности), из ссылок того проекта (по факту - тоже сборки), на который ссылается текущий. Так что для использования какой либо сборки (в данном случае - из состава пакета), ссылку на нее нужно добавлять в проект явно.
    Ответ написан
    2 комментария