Задать вопрос
  • Как отредактировать сообщение с картинками в группе Telegram через api bot?

    Razbezhkin
    @Razbezhkin
    программист, преподаватель
    А где используется полученный $media_group_id?
    Ответ написан
    Комментировать
  • Где искать TraceId из OpenTelemetry в Jaeger и как связывать микросервисы?

    Razbezhkin
    @Razbezhkin Автор вопроса
    программист, преподаватель
    В общем, не все так просто как казалось.
    Пришлось скачать исходники opentelemetry https://github.com/open-telemetry/opentelemetry-dotnet и посмотреть, как устроено распространение трассировочной информации в инструментарии AspNetCore.

    Сохранение, передача и восстановление TraceID (и доп информации) называется Propogation.
    В пакете OpenTelemetry Есть специальный класс:
    OpenTelemetry.Context.Propagation.Propagators
    Который возвращает этих пропогаторов с помощью которых производиться внедрение и извлечение контекстной информации (информации о трассировке).

    Чтобы куда-нибудь внедрить данные о трассировке, можно использовать примерно такой код:

    //достаем текстового распространителя
    var textMapPropagator = Propagators.DefaultTextMapPropagator;
    //формируем контекст распространения
    var propContext = new OpenTelemetry.Context.Propagation.PropagationContext(Activity.Current.Context, Baggage.Current);
    //этот метод вызывает для каждого необходимого значения их контекста распространения ваш же метод, который сохраняет пару ключ-значения для последующего восстановления
    textMapPropagator.Inject(propContext,context, (ctx, name, val) =>
    {
        ctx.Headers.Set(name,val);
    });


    На другой стороне нужно контекст трассировки восстановить. код примерно такой:

    //извлекаем из среды распространяемую трейс-информацию
            var propagator = Propagators.DefaultTextMapPropagator;
            PropagationContext propagationContext = propagator.Extract(default, context,
                (ctx, name) => { return new string[] { ctx.Headers.Get<string>(name) }; });
    
            if (propagationContext.ActivityContext.IsValid())
            {
                //формируем новый спан.
                newOne = new Activity("Consumer");
                newOne.SetParentId(propagationContext.ActivityContext.TraceId,
                    propagationContext.ActivityContext.SpanId,
                    propagationContext.ActivityContext.TraceFlags);
                newOne.TraceStateString = propagationContext.ActivityContext.TraceState;
                newOne.Start();
                newOne.IsAllDataRequested = false;
    
                Baggage.Current = propagationContext.Baggage;
            }


    в результате контекст трассировки восстанавливается и в Jaeger попадает в связанном виде.
    Единственная проблема в том, что именно этот Span не сохраняется (хотя все последующие в цепочке - да) и появляется Warning вида: "invalid parent span IDs=b3f757a84de75eda; skipping clock skew adjustment"
    Что с ним делать - пока не знаю. чего-то все такие не хватает
    Ответ написан
    1 комментарий
  • Как обработать возврат на предыдущую страницу во Flutter?

    Razbezhkin
    @Razbezhkin
    программист, преподаватель
    Вот как я решил такую задачу для сценария, когда пользователь нажимает стрелку "назад" на самом устройстве, чтобы определенная страница смогла отловить тот самый момент когда страница извлекается из истории и показывается пользователю.

    Я добавил миксин "RouteAware" в тот класс, который является страницей, и перегрузил метод didPopNext.
    вот пример.

    //страница
    class CartPage extends StatefulWidget {
      @override
      _CartPageState createState() {
        return _CartPageState();
      }
    }
    
    //состояние страницы
    class _CartPageState extends State<CartPage> with RouteAware {
        //вызывается, когда на эту страницу происходит возврат.
      @override
      void didPopNext() {
        _loadCart();
      }
    }
    Ответ написан
    Комментировать
  • Как в ubuntu добавить Root CA от latsencrypt.org чтобы docker pull мог скачать его из собственного реестра образов?

    Razbezhkin
    @Razbezhkin Автор вопроса
    программист, преподаватель
    Решение оказалось таким:
    в папке /etc/docker/certs.d создать папку по имени совпадающую с именем хоста репозитория образов (например, my-https.registry.example.com) и в нее скопировать полученные от LetsEncrypt сертификаты с открытым ключом, это обычно файлы certificate.crt и ca_bundle.crt

    Об этом написано в документации https://docs.docker.com/engine/security/certificates/

    Всем откликнувшимся огромное спасибо!
    Ответ написан
    Комментировать
  • Как хранить дату и время с учетом часового пояса в sql server + C# и отображать через javascript?

    Razbezhkin
    @Razbezhkin Автор вопроса
    программист, преподаватель
    Организовать это можно так:
    1. Для столбца таблицы используем тип «datetimeoffset»
    2. Чтобы присваивать через C#, используем тип данных DateTimeOffset и его свойство Now
    3. Для передачи на клиент (например через ajax) используем стандартную сериализацию (например, через Newtonsoft.Json), получиться строка типа «2019-10-07T09:38:10.5016691+05:00», в которой указывается местное время (сервера) и его часовой пояс.
    4. На клиенте эту строку используем для создания объекта даты, и выводим в локальном времени пользователя, например, так: (new Date(datestring)).toLocaleString()
    Ответ написан
  • Как правильно связать пагинацию с vue-router?

    Razbezhkin
    @Razbezhkin Автор вопроса
    программист, преподаватель
    В ходе разных экспериментов я пришел к такому выводу:
    Если мы хотим сделать страницу (компонент|view) чтобы соблюдались такие условия:
    - у компонента есть параметры, влияющие на его отображение (например, номер страницы списка и/или фильтры)
    - мы хотим чтобы в url отражались эти параметры и можно было сохранить ссылку на компонент в таком виде
    - чтобы при открытии страницы по ссылке внешний вид компонента восстанавливался.
    - если мы ходим вперед/назад в браузере, то восстанавливается состояние, соответствующее истории браузера.

    То нам следует писать компонент следующим образом:
    1. Все параметры, которые мы хотим иметь в url необходимо изменять через маршрутизацию при помощи элемента "router-link", или атрибутов "to" некоторых элементов, или при помощи this.$routes.push. При этом ссылка должна быть такой, чтобы все параметры, кроме изменяемого были такими же.

    Например, у нас есть номер страницы, размер страницы и категория, которые должны быть в url, чтобы пользователь мог пересылать ссылку на определенную страницу определенной категории. Таким образом, ссылки пагинатора должны иметь вид:
    /goods?page=1&ps=20&catid=10, /goods?page=2&ps=20&catid=10, /goods?page=3&ps=20&catid=10
    соответственно, если у нас будет 50 параметров, которые мы должны отражать, то нам нужно будет организовать адреса переходов для 50 параметров, причем для всех компонентов, которые меняют эти параметры, для этого, наверное, нужно написать какой-нибудь велосипед, который берет текущие параметры урлов, меняет (или добавляет) в них какой-то один и генерирует новый адрес перехода.

    2. нужно написать в компоненте метод инициализации, который при помощи параметров в url восстанавливает состояние компонента.

    3. в хуке жизненного цикла mounted и в watch'ере маршрутизатора ($route) вызывать метод инициализации из п.2.

    4. (это п.1 наоборот) нельзя напрямик (без перехода через маршрутизатор) менять состояние при изменении любого параметра влияющего на состояние, т.е. пагинатор не должен просто менять переменную, отвечающую за номер страницы и обновлять массив загруженных товаров - это не изменит url, и следовательно не позволит получить правильную ссылку.

    Насколько это нормальное решение? есть ли у кого-то более изящное? как делаете вы?
    Спасибо.
    Ответ написан
    2 комментария
  • Как эффективно разрабатывать код на javascript?

    Razbezhkin
    @Razbezhkin Автор вопроса
    программист, преподаватель
    есть, вроде бы возможность запускать функции js в среде nodejs, и как-то прикрутить к этому делу отладчик, видимо буду копать в этом направлении, если вам знакомы такие подходы, поделитесь, пожалуйста.
    Ответ написан
    Комментировать
  • Должны ли dll’ки из nuget пакетов автоматически копироваться во все проекты с косвенными ссылками в VisualStidio?

    Razbezhkin
    @Razbezhkin Автор вопроса
    программист, преподаватель
    Я провел эксперимент: в решении два проекта, первый проект (.net standard 2.0) ссылается на nuget пакет, второй проект (.net framework 4.7.2) ссылается на первый. Построение решения происходит успешно, но при запуске второго проекта возникает ошибка: не удалось загрузить сборку из nuget пакета. от сюда вывод - при построении зависимости из nuget пакетов, которые непосредственно не содержатся в проекте не копируются в выходную папку.

    Еще я нашел статью: https://terryaney.wordpress.com/2018/05/06/msbuild... в которой это подтверждается и решение заключается в использовании MSBuild со своей конфигурацией. А вот подключать nuget пакеты ко всем проектам - подход не самый лучший (хотя самый простой).

    Я продолжил экспериментировать:
    Создал нулевой проект (.net standard 2.0) на который ссылается только первый проект. При построении и запуске второго проекта все зависимости были разрешены, приложение запустилось без проблем.

    И еще один эксперимент:
    Я создал четвертое приложение, но уже .net core 2.1, которое ссылается только на проект 1, и к моему удивление при его сборке и запуске все зависимости, включая nuget пакет были разрешены, запуск произошел успешно.

    Видимо, .net standard и .net core проекты строятся не так, как это делают .net framework проекты.
    Ответ написан
    2 комментария
  • Как в EntityFramework настроить отношения между таблицами, которые ссылаются друг на друга по внешнему ключу?

    Razbezhkin
    @Razbezhkin Автор вопроса
    программист, преподаватель
    Спасибо Толстый Лорри, за подсказку.
    Действительно, без указания ссылки на коллекцию записей в дочерней таблице в виде вот такого свойства:

    public virtual ICollection Messages { get; set; }

    EF не мог понять, в каких отношениях находятся эти две таблицы.
    но этого оказалось недостаточно, т.к. все равно существовала неоднозначность, которую получилось разрешить при помощи атрибута InversePropertyAttribute, который я добавил перед этим самым свойством.

    в результате структура классов стала вот такой:

    public class ForumTopic
    {
            [Key, DatabaseGenerated(System.ComponentModel.DataAnnotations.Schema.DatabaseGeneratedOption.Identity)]
            public int TopicId { get; set; }
            public int LastMessageId { get; set; }
            [ForeignKey("LastMessageId")]
            public virtual ForumMessage LastMessage { get; set; }
            [InverseProperty("Topic")]
            public virtual ICollection<ForumMessage> Messages { get; set; }
    }
    
    public class ForumMessage
    {
            [Key, DatabaseGenerated(System.ComponentModel.DataAnnotations.Schema.DatabaseGeneratedOption.Identity)]
            public int MessageID { get; set; }
            public int TopicID { get; set; }
            [ForeignKey("TopicID")]
            public virtual ForumTopic Topic { get; set; }
    }
    Ответ написан
    Комментировать
  • Как на c# организовать взаимодействие с другим процессом через stdin и stdout?

    Razbezhkin
    @Razbezhkin Автор вопроса
    программист, преподаватель
    Спасибо rPman
    !
    заменил в питоновом скрипте print на
    sys.stdout.write('mytextdata\n')
    sys.stdout.flush()

    и код на c# стал получать данные своевременно!
    Ответ написан
    Комментировать
  • Как указать сборку при создании объекта?

    Razbezhkin
    @Razbezhkin Автор вопроса
    программист, преподаватель
    Нашел решение на которое меня натолкнул DENIS
    в файле кода в самом верху ставим такой код:
    extern alias myassembly;

    при обращении к классу используем такой синтаксис:
    myassembly::namespace.classname.staticmethod1();

    и еще в свойствах ссылки на сборку (Solution Explorer -> Project -> References -> myassembly.dll -> Properties), находим параметр "псевдоним" (alias), в котором по умолчанию написано "global", и через запятую добавляем ему "myassembly", т.е. тот идентификатор, который мы в самом начале указывали в extern alias.
    После этого все компилируется и работает.
    Спасибо DENIS!
    Ответ написан
    Комментировать
  • Как кэшировать результаты Entity Framework без Lazy Load и подключенного соединения к БД?

    Razbezhkin
    @Razbezhkin Автор вопроса
    программист, преподаватель
    Спасибо.
    Оказывается, в DB контексте есть специальные настройки, которые могут напрочь отрезать сущности от контекста:
    вот кусочек кода, который настраивает контекст:

    CFDB rocontext = new CFDB();
    rocontext.Configuration.ProxyCreationEnabled = false;//запрещает использовать прокси классы - на выходе у нас те самые типы, которые мы определяли в моделях
    rocontext.Configuration.LazyLoadingEnabled = false;//здесь запрещается использовать отложенную подгрузку данных, и если мы не указали в Include сущности, которые нам понадобятся, то получим исключение
    rocontext.Configuration.ValidateOnSaveEnabled = false;//отключает проверку при сохранении, а сохранение вообще не подразумевается
    rocontext.Configuration.AutoDetectChangesEnabled = false;//отключает проверку на наличие изменений при сохранении, а сохранение вообще не подразумевается

    вроде бы такой вариант меня устраивает - ничего кроме нужных мне сущностей не остается и их можно безопасно кэшировать.
    Ответ написан
    Комментировать
  • Как привязать домен к динамическому поддомену?

    Razbezhkin
    @Razbezhkin
    программист, преподаватель
    Во первых, нужно организовать настройку DNS на котором находиться доменная зона так, чтобы там существовала запись A или CNAME которая будет ссылаться на адрес веб сервера. Если это имя username.mydomain.ru, то тут проще: находим DNS хостинг в котором есть API для редактирования зон и правим зону mydomain.ru, добавляя в нее запись username. Если же это домен пользователя, такой как username.ru, тогда придется заставлять пользователя править свою зону самому.

    Во вторых на веб сервере настраиваем привязку вебсервера к ip адресу без привязки к домену, так, чтобы он обрабатывал все запросы на 80 порт.

    Детали реализации зависят от тех технологий, который вы используете и от api dns хостинга.
    Ответ написан
  • Как спрятать элемент сайта на определенном домене?

    Razbezhkin
    @Razbezhkin
    программист, преподаватель
    Уточните, пожалуйста, вам нужно, чтобы скрипт работал на клиентской стороне или на серверной. если на серверной, то какая у вас там платформа?
    Ответ написан
    1 комментарий
  • Как получить доступ к web.config из unit test'ов для asp.net mvc проекта?

    Razbezhkin
    @Razbezhkin Автор вопроса
    программист, преподаватель
    Нашел рабочий ответ:
    stackoverflow.com/questions/516233/how-to-use-web-...
    Ответ написан
    Комментировать
  • Расположение одной картинки над другой при помощи css

    Razbezhkin
    @Razbezhkin Автор вопроса
    программист, преподаватель
    Спасибо за ваши советы!
    Ответ написан
    Комментировать
  • Отслеживание прогресса кэширования изображений?

    Razbezhkin
    @Razbezhkin Автор вопроса
    программист, преподаватель
    Спасибо!
    Ответ написан
    Комментировать
  • Изучение (моё) AngularJS на примере?

    Razbezhkin
    @Razbezhkin Автор вопроса
    программист, преподаватель
    Вот, собственно, созрел еще один вопрос.
    как лучше всего (правильнее с идеологической точки зрения) в ячейки вставлять html элементы управления в зависимости от типа.
    варианты содержимого следующие:
    ссылка «записаться»
    текст «занято» на желтом фоне
    текст «занято» на красном фоне
    текст «вы записаны — не подтверждено», ссылка «выписаться»
    текст «вы записаны — подтверждено», ссылка «выписаться»

    Я попробовал сделать это через compile. но пока ничего не получилось:

    <td ng-repeat="day in days"><div compile="showreserv(room,day)"></div></td>
    


    Подскажите, пожалуйста, куда копать.
    Ответ написан
    Комментировать
  • Изучение (моё) AngularJS на примере?

    Razbezhkin
    @Razbezhkin Автор вопроса
    программист, преподаватель
    Я немного продвинулся в своем изучении.
    Если структура данных о резервировании содержит объекты, в которых есть поле id — которое обозначает номер помещения и date — которое обозначает дату, то привязку к ячейкам можно сделать следующим образом:

    В javascript'е вставить следующий код:

    $scope.showreserv = function (room, day) {
                var x = $filter('filter')($scope.reservs, { id: room.id, date: day });
    
                if (x.length > 0) return x[0].type;
                else return "-";
            }
    
    


    а в html'е следующий:

    <tr ng-repeat="room in stores|orderBy:'name'">
    <td ng-click="test(room)">{{room.id}} {{room.name}}</td>
    <td ng-repeat="day in days">{{showreserv(room,day)}}</td>
    </tr>
    


    коллекция stores содержит информацию о пемещениях, поле id — идентификатор, name — название
    коллекция days — содержит дни, начиная с сегодня. (в массиве содержатся целые числа timestamp)
    вот этот кусок html кода

    <td ng-repeat="day in days">{{showreserv(room,day)}}</td>
    


    повторяется для каждого помещения и дня и при каждой привязке вызывается функция showreserv. Ее код — выше.

    фильтрация — обалденная штука (хотя додумался как с ней работать не сразу)

    var x = $filter('filter')($scope.reservs, { id: room.id, date: day });
    


    здесь $scope.reservs — массив всех резервирований.
    а { id: room.id, date: day } — обозначает что в результате должны остаться только те элементы, у который поля id и date соответствуют входным параметрам функции привязки.

    тут у меня был один ньюанс: фильтр не работал, пока дата в коллекциях была представлена объектом Date. видимо, разные экземпляры не сравнивались. когда вместо объектов Date я стал использовать целое число timestamp — все встело на свои места.

    Теперь мне нужно сделать следующие вещи:
    1. отображать в ячейках таблицы разные шаблоны для каждого значения типа резервирования и при отсутствии резервирования.
    2. привязать к ячейкам обработчик клика
    3. сделать так, чтобы данные отправлялись на сервер.
    Ответ написан