• Существует ли микроразметка для фактов?

    Можно, к примеру, при помощи разметки RDFa:
    ответ от ИИ
    <!DOCTYPE html>
    <html xmlns="http://www.w3.org/1999/xhtml"
          xmlns:vocab="http://schema.org/"
          prefix="vocab: http://schema.org/">
    <head>
      <title>RDFa Fact Example</title>
    </head>
    <body>
      <div typeof="vocab:Fact">
        <span property="vocab:statement">Земля круглая.</span>
      </div>
    </body>
    </html>
    Ответ написан
    Комментировать
  • С чего начать создание магазина под SEO?

    Kadzi
    @Kadzi
    Ом
    — Мне нужно SEO, Игорь. Я запускаю прибыльный магазин по продаже белья. Между прочем на ларавель. Вопросы?
    — Я понял, Олег. Скажите, а в чем полезное действие вашего магазина?
    — Ладно, вообщем смотри: есть ниша, постельное белье, уже собиралась семантика, сказали что неправильно. Я как ты понял в вопросе разобрался и вижу, что нужно подготовить структуру и категории.
    — Я вас понял, Олег. Скажите, а чем ваш магазин будет отличаться от тысячи таких же?
    — Ха, ну ты приколист Игорь. У меня белье марки Лёвушка, таких в интернете нет, конкуренции тоже.
    — Я вас понял, Олег. Скажите, а почему вы так часто упоминаете сеошника?
    — Почему, почему! Потому!
    — Вы упомянули, что про сео знаете достаточно мало. А достаточно ли вы знаете про маркетинг? Про информационные архитектуры? Хорошо ли вам известно о продажах? О психологии? — не останавливался Игорь, — О дизайне вам хорошо известно?
    — Не грузи меня Игорь. Ты тупой? У меня есть деньги, товар и идея. Мне нужно сделать правильную структуру, собрать семантику и запустить продвижение. Сложно что ли подсказать как правильно?
    — Я вас понял, Олег. А каково полезное действие магазина?
    — Блин, что за вопрос? Человек ищет товар в интернете, попадает на мой сайт, покупает.
    — А почему покупает? — уточнил Игорь.
    — ДА ПОТОМУЧТО В ТОПЕ! — вскипел Олег.
    — Я вас понял, Олег. А почему вы хотите создать магазин под SEO, а не под людей?
    — Игорь я думал ты разбираешься...Что не понятно то? Чтобы человек нашел мой товар, сайт где должен быть? Во-о-о-т, в ТОПе. А чтобы быть в ТОПе, нужно что? SEO продвижение. Я уже делал магазины и зарабатывал на них, че ты понтуешься тогда?

    ps я устал, но за 10 лайков быть может продолжу :-))
    Ответ написан
    2 комментария
  • Как на сегодняшний день интернет-магазины парсят товары?

    8Alfa
    @8Alfa
    веб-разработчик, фотограф, менеджер по продажам
    Действительно, все зависит от компании, которая нуждается в этом парсере.
    И как бы она не старалась, найдутся таките, кто не захочит предоставлять данные в необходимой форме.

    В одной продажной компании делали заказ программистам, которые специально разрабатывают парсеры под любые запросы. Никого не беспокоят, просто все грабят с нужного вебсайта (с согласия поставщика, разумеется).
    Каждый вебсайт по цене, зависящей от количества товаров.

    И они надолго обеспечены работой на огромном оптовом вещевом рынке с тысячами продавцов и сотнями интернет-магазинов.
    Ответ написан
    Комментировать
  • Как настроить сервер для отладки вебхуков (webhooks) на локальной машине??

    Mike_Ro
    @Mike_Ro
    Python, JS, WordPress, SEO, Bots, Adversting
    1. Сбилдить .NET приложение в докере.
    2. Развернуть докер контейнер на сервере.
    3. Развернуть nginx (тоже можно в контейнере) на сервере.
    4. Настроить nginx, который будет проксировать трафик в п2:
    4.1. Запретить все.
    4.2. Разрешить :80 и :443 порты.
    4.3. Пробросить с п4.2 на внешний порт контейнера п2.
    4.4. Настроить SSL Let's Encrypt (при необходимости).

    По сути, можно взять любое руководство настройки докера и nginx, без привязки к .NET.

    UPD на основе данных из комментариев, конфиги будут выглядеть примерно так, dockerfile (поправить под свое приложение):
    # Образ asp.net.
    FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base
    WORKDIR /app
    EXPOSE 80
    EXPOSE 443
    
    # Компилируем приложение из /src.
    FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
    WORKDIR /src
    
    # Копируем файл проекта и восстанавливаем зависимости.
    COPY ["Project.csproj", "."]
    RUN dotnet restore
    
    # Копируем оставшиеся файлы и компилируем приложение.
    COPY . .
    RUN dotnet build -c Release -o /app/build
    
    # Публикуем приложение.
    FROM build AS publish
    RUN dotnet publish -c Release -o /app/publish
    
    # Создание итогового образа.
    FROM base AS final
    WORKDIR /app
    COPY --from=publish /app/publish .
    ENTRYPOINT ["dotnet", "App.dll"]

    nginx (поправить под свое приложение):
    # http.
    server {
        listen 80;
        listen [::]:80;
        # Домены для обслуживания.
        server_name domain.ru www.domain.ru;
    
        # 301 редирект http->https.
        return 301 https://$host$request_uri;
    }
    
    # https.
    server {
        listen 443 ssl;
        listen [::]:443 ssl;
        # Домены для обслуживания.
        server_name domain.ru www.domain.ru;
    
        # Пути до letsencrypt сертификатов.
        ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem;
    
        ssl_protocols TLSv1.2 TLSv1.3;
        ssl_prefer_server_ciphers on;
        ssl_ciphers "ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256";
    
        location / {
            # Адрес, по которому доступно приложение на локалке сервера (localhost не указывать, а указывать имя контейнера (project в моем случае)).
            proxy_pass http://project:80;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $scheme;
        }
    }

    P.S. рекомендую освоить Docker Compose, чтобы было меньше возьни с разворачиванием и общением между контейнерами.
    Ответ написан
    8 комментариев
  • Как сделать Bulk update методами LINQ (Entity Framework Core) дополнительной таблицы при связи много-ко-многим?

    AshBlade
    @AshBlade Куратор тега C#
    Просто хочу быть счастливым
    Для данного случая предлагаю update в цикле, обернутую в транзакцию.
    Так как даже в SQL такое не выразить

    Примерно так
    public async Task ApplyRange(Guid pharmacyId, IEnumerable<(Guid id, int count)> products)
    {
        await _table.BeginTransactionAsync();
        for (var (id, count) in products)
        {
              await _table.Where(e => e.PharmacyId == pharmacyId && e.ProductId == id)
                                  .ExecuteUpdateAsync(entity => entity.SetProperty(x => x.Count, x => x.Count + count))
        }
        await _table.CommitTransactionAsync();
    }


    Единственная проблема здесь в множественных RTT при каждом запросе, но все нивилируется тем, что выполняется в транзакции, т.е. большая задержка будет при коммите. Но рекомендую найти какую-нибудь либу, которая будет батчить подобные операции

    P.S.
    1. Есть CreateExecutionStrategy, который и реализует семантику транзакции
    2. Код писал здесь в редакторе, поэтому может даже не компилироваться - главная задача дать идею
    Ответ написан
    4 комментария
  • Десериализовать массив JSON?

    Mike_Ro
    @Mike_Ro
    Python, JS, WordPress, SEO, Bots, Adversting
    Насколько я помню, для десериализации массива строк json в List не требуется передавать отдельный класс DeserializationJson, можно использовать сразу JsonSerializer.Deserialize<List<string>>, попробуйте так:
    using System.Text.Json;
    
    namespace ReflTest;
    
    internal class DesJson
    {
        public IEnumerable<string> RunDesir(string jsonString)
        {
            var result = JsonSerializer.Deserialize<List<string>>(jsonString) ?? Enumerable.Empty<string>();
            return result.Select(item => item.ToString());
        }
    }
    
    class Program
    {
        static void Main(string[] args)
        {
            string jsonString = "[\"1\",\"2\",\"3\",\"4\",\"5\"]";
            DesJson desJson = new DesJson();
            IEnumerable<string> result = desJson.RunDesir(jsonString);
            result.ToList().ForEach(Console.WriteLine);
        }
    }
    Ответ написан
    Комментировать
  • Как в react работать с большим количеством данных?

    Kentavr16
    @Kentavr16
    long cold winter
    Путей решений большое количество, и они зависят от твоих хотелок.
    Вариант а - с кульбитами, но я бы так сделал. Пишешь небольшой бекенд на экспрессе для своего приложения. На беке с помощью cron например раз в день/час/несколько минут делаешь запрос на нужное апи, записываешь в своей бд ответ. Вопрос с лимитом запросов решен. далее делаем пагинацию на своем сервере (очень простое действие) и отправляешь пользователю человеческий ответ по АПИ, который будет соответствовать всем твоим запросам и нуждам. На фронте остается допилить простое СПА без извращений и сложностей.
    Вариант б - сохраняешь ответ на клиенте, обновляешь кеш раз за n-ное время, как предложено выше. В таком случае проще всего действительно использовать локалстор для хранения ответа по АПИ. Если хочется более продвинутой работы, обрати внимание на indexedDB -есть несколько интересных адаптеров для реакта, которые упрощают работу.
    Вопрос с сохранением данных при переходе на другую страницу решается просто (я догадываюсь что под другой страницей ты подразумеваешь роутинг в react SPA). Это либо хранение состояния на верхнем уровне приложения, либо стейт менеджер. Внимание - стейт-менеджер только упрощает(!!!) обращение со сложным стейтом в относительно больших приложениях. Это не панацея, по факту он делает то же самое что и обычный хук стейта. Тебе скорее всего не принципиально, но при желании пришить условный zustand можно. Это вкусовщина.
    Можно вообще написать кастомный хук для работы с локалстором/индекседДБ и юзать на каждой странице, считывая при заходе на каждую страницу данные и одновременно проверяя их "свежесть". Тогда стейт менеджеры точно не нужны от слова совсем.
    Ответ написан
    1 комментарий
  • Как сделать, чтобы браузер, открытый при помощи Selenium работал как с мобильного телефона?

    Mike_Ro
    @Mike_Ro
    Python, JS, WordPress, SEO, Bots, Adversting
    Как сделать, чтобы браузер, открытый при помощи Selenium работал как с мобильного телефона?

    У одного веб приложения есть проверка на текущее устройство.

    Никак, пока не будет известен алгоритм детекта НЕ мобильного устройства. Но, как вариант, использовать один из следующих методов (от простого к сложному):
    1. Открыть инструменты разработчика браузера, активировать "toggle device toolbar" и задать ширину и высоту дисплея, равную мобильному устройству (условно чекается).
    2. Использовать Appium + Android Virtual Device (слабо чекается).
    3. Использовать Appium + настоящий смартфон (слабо чекается).
    4. Использовать собственный браузер (не чекается).

    P.S. про всякие заголовки, ip, куки, локальные хранилища, частота подключений итп даже говорить не будут, это дефолт.
    Ответ написан
    Комментировать
  • Как подключить бд к серверу в docker-compose?

    Mike_Ro
    @Mike_Ro
    Python, JS, WordPress, SEO, Bots, Adversting
    Server=localhost

    Чей локалхост? У каждого контейнера он свой. Тогда какой указывать? Оптимально - по имени.
    https://docs.docker.com/compose/networking/
    Reference containers by name, not IP, whenever possible. Otherwise you’ll need to constantly update the IP address you use.

    Port=6002

    Чья туфля порт? Внутри докер-сети (Вы же указали: networks>postgres-network) контейнеры общаются по внутренним портам (рекомендуется).

    Если резюмировать, то будет примерно так (поправить местами при необходимости):

    "Postgres": "Server=localhost; Port=6002; Database=post; User ID=postgres; Password=passwd; Pooling=true"

    "Postgres": "Server=postgres_db; Port=5432; Database=post; User ID=postgres; Password=passwd; Pooling=true"

    docker-compose.yml:
    version: '3.8'
    
    networks:
      postgres-network:
        driver: bridge
    
    services:
      gchain.posts.api:
        image: gchain.posts.api
        build:
          context: .
          dockerfile: GChain.Posts.Api/Dockerfile
        ports:
          - "80:8080"
        networks:
          - postgres-network
        depends_on:
          - postgres_db
    
      postgres_db:
        container_name: postgres_post
        image: postgres:latest
        environment:
          POSTGRES_USER: ${POSTGRES_USER:-postgres}
          POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-passwd}
          POSTGRES_DB: post
        volumes:
          - postgres-data:/var/lib/postgresql/data
        ports:
          - "6002:5432"
        networks:
          - postgres-network
        restart: unless-stopped
    
    volumes:
      postgres-data:
    Ответ написан
    Комментировать
  • Как подружить MVC с реляционной базой данных?

    AshBlade
    @AshBlade Куратор тега C#
    Просто хочу быть счастливым
    Сложные объекты, как раз могут передаваться, просто надо сделать формы другим образом. Скорее всего ты в этот asp-form передаешь всю модель. Предполагаю, что вся модель - это Address.
    Да, из вложенных сложных структур плохо создаются формы. Для решения тебе надо будет форму вручную: все поля и их связь с моделью прописывать самому. Есть шаблонные помощники (Html.EditorFor и другие) - используй их.
    Например, так (внимание, написал по воспоминаниям, может даже не компилироваться)
    @Html.BeginForm() 
    {
          <label>Страна</label>
          @Html.EditorForModel(x => x.Country)
          <label>Город</label>
          @Html.EditorForModel(x => x.City)
    }


    Кроме этого, есть пара других советов:
    1. Создай специальные DTO классы, которые будут потом отображаться в эти объекты БД.
    2. Раз ты делаешь через asp-form, то лушче добавь специальные атрибуты валидации: EmailAddress, Range и т.д.

    P.S. в 1 пункте проблема глубже, чем простой маппинг. Если делать такой подход, который показан:
    - Изменения схемы БД потребуют изменения UI
    - Клиент может передать данные, о которых он знать не должен (например, добавишь новое поле куда-нибудь и оно случайно обновится)
    Ответ написан
    2 комментария
  • Как правильно тестировать базу данных в .NET?

    AshBlade
    @AshBlade Куратор тега C#
    Просто хочу быть счастливым
    Решение простое - создаешь мок БД для тестов.
    1. Тест начинается - запускаешь БД и заполняешь данными необходимыми (как сказал Василий Банников можно сделать дамп с удаленными чувствительными данными)
    2. После каждого теста необходимо выполнить откат - если какие-то данные были добавлены/удалены/изменены
    3. При завершении тестирования удаляешь БД

    На мой взгляд, здесь просто много инфраструктурной работы. Полезные инструменты:
    1. Testcontainers - запускаешь БД в контейнере. Сам ей пользовался, есть много шаблонов для разных БД, чтобы с нуля не писать все. Можно также скрипт инициализации (схема, дамп) добавить - вот тебе и настройка
    2. В зависимости от фреймворка есть разные механизмы запуска кода после каждого тест-кейса. Если про xUnit, то:
      1. Тестовый класс реализует IDisposable - выполняется после каждого тест-кейса. Можно тут реализовать логику отката БД
      2. Для инициализации самого контейнера (чтобы каждый раз не запускать заново) - IClassFixture



    Также никто не отменял внешний инстанс БД использовать - просишь дба создать отдельную БД специально для тестов, просто запускать теперь параллельно не получится
    Ответ написан
    Комментировать
  • Какие есть оптимальные способы хранения и передачи изображений из MongoDB?

    VoidVolker
    @VoidVolker
    Dark side eye. А у нас печеньки! А у вас?
    Да, есть: хранить сами изображения не БД, а в отдельном файловом хранилище с внешним доступом по ссылке-идентификатору. В самой же БД хранить только идентификаторы изображений в хранилище. Это стандартная практика работы с файлами и БД.
    Ответ написан
    Комментировать
  • При генерации кошельков должна генерироваться seed-фраза из 12 слов с проверкой checksum, как это понять?

    Noizefan
    @Noizefan
    последнее слово из 12 это хеш-сумма предыдущих 11, мой дорогой фуллстак.
    при генерации ты должен проверить, что это не от балды напиханные 12 слов, а соответствующая спецификации настоящая мнемоника, хешанув 11 слов и получив именно двенадцатое.
    Ответ написан
    Комментировать
  • С чем и как есть gRPC?

    AshBlade
    @AshBlade
    Просто хочу быть счастливым
    1-2. Если говорить про микросервисы: каждый микросервис должен определять свою модель пользователя (только те поля/данные которые нужны конкретно ему) - да это будет копипаст

    Если про реальность: все зависит от области - возможно стоит сделать несколько независимых (в контексте запускаемых процессов) сервисов, но все они будут шарить единственную модель, а может для каждого свою определить.

    3. Зависит
    4. Обычно, для популярных ЯП (ты не указал, но в тегах есть питон) есть официальные библиотеки с кодогенерацией - юзай их
    5. Какой архитектуры? Если про gRPC vs HTTP, то лучше копай в строну понимания синхронного (HTTP, TCP, gRPC) и асинхронного (очереди сообщений) взаимодействия
    Ответ написан
    2 комментария
  • Что выбрать для CI/CD проектов на .net?

    VoidVolker
    @VoidVolker
    Dark side eye. А у нас печеньки! А у вас?
    • Самое ближайшее и доступное в вашем случае - GitHub Actions
    • Чуть более сложно, но больше гибкости и автономности - GitLab PipeLines (можно даже у себя захостить сервер)
    Ответ написан
    2 комментария
  • Стоит ли заниматься по курсам от Ulearn?

    vabka
    @vabka
    Токсичный шарпист
    ulearn - вполне хорошие курсы университетского уровня.
    Причём это не "курсы C#", а "курсы программирования, на примере C#", что для новичка даже лучше.
    Ответ написан
    Комментировать
  • Возможно чтобы код С# испольнялся на GPU?

    @rPman
    Погуглю за тебя.
    ilgpu.net, первый же пример.

    Возможно ты что то не то хочешь, и лучше бы тебе сначала посмотреть в сторону opencl, язык там будет похожий на c++, заточен на работу на многопроцессорных ускорителях типа видеокарта. Есть даже реализации для fpga чипов с программируемой логикой, в общем это специализированный стандарт.

    Есть еще cuda, это vendorlock модификация opencl от nvidia (формально это они двигают стандарты в этом направлении, ибо крупнейшие разработчики железа)
    Ответ написан
    Комментировать
  • Как правильно обучаться в начале пути?

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

    "Насчёт паттернов, принципа SOLID и подобных штук": для их изучения необходим опыт, хотя бы говнокодинга, и точка приложения, хотя бы тот же собственный говнокод, в котором груда классов перепутана между собой. Разгребание этой груды позволит применить те принципы на практике, а без практики их изучать бесполезно вовсе.
    Ответ написан
  • Как сделать самоподписанный сертификат доверенным на Windows?

    saboteur_kiev
    @saboteur_kiev Куратор тега Windows
    software engineer
    У сертификата есть поле Common Name или Certificate Subject, там где ты указывал имя при генерации сертификата.
    Оно должно соответствовать имени домена (например localhost)

    Либо у сертификата есть дополнительное поле Alternative Subject Names, где можно перечислить несколько DNS имен, тогда localhost должен быть или там или там.
    Иначе не пройдет валидация, браузер не будет видеть что сертификат соответствует твоему сайту localhost
    Ответ написан
    Комментировать
  • Что означает оператор => в linq c#?

    vabka
    @vabka Куратор тега C#
    Токсичный шарпист
    Это не оператор, а стрелочка, которая отделяет аргументы анонимной функции от её тела.
    https://learn.microsoft.com/en-us/dotnet/csharp/la...

    Тоесть вот такой код создаёт функцию с единственным аргументом num, которая возвращает значение выражения num != 2.
    num=>num!=2

    Ведь эта строка на много проще

    Нет, не проще.

    Выбирай:
    var noTwo = nums.Where(x=>x != 2);
    // или
    var noTwo=from num in nums
                      where num!=2
                      select num;
    Ответ написан
    Комментировать