Ответы пользователя по тегу ASP.NET
  • Как принудительно разлогинить пользователя в случе бана?

    vabka
    @vabka Куратор тега ASP.NET
    Токсичный шарпист
    1. Заводишь какую-нибудь табличку для бан-листа, в которую записываешь идентификаторы каждого клиента, которые забанены. (Предварительно тебе бы следовало как-нибудь запомнить, что клиент с таким-то идентификатором от некоторого oidc-провайдера является таким-то пользователем в твоей системе.)

    2. Вносишь его токен в чёрный список до тех пор, пока у токена не истечёт время жизни. (для списка таких токенов тоже следует завести табличку)

    3. Естественно, во всех местах ты должен проверять, что токен не внесён в чёрный список, не отозван, и что сам пользователь не забанен. В случае провала такой проверки - кидай 403 код ошибки, а на фронте при получении такого кода - выводи какое-нибудь сообщение.
    Ответ написан
    Комментировать
  • Как валидировать только структуру запроса, но не данные?

    vabka
    @vabka Куратор тега ASP.NET
    Токсичный шарпист

    сразу отвечу на вопрос, что Required у него стоит для Swagger'a и убирать его не хотелось бы

    Атрибуты - это не единственный вариант создать схему.
    Посмотри в той библиотеке, которую ты используешь, может там есть атрибут для добавления произвольных данных в схему?

    + Ты можешь в принципе отключить валидацию из asp net mvc

    services.Configure<ApiBehaviorOptions>(options =>
            {
                options.SuppressModelStateInvalidFilter = true;
            });
    Ответ написан
    3 комментария
  • Как правильно записать Guid в юнит тесте?

    vabka
    @vabka Куратор тега ASP.NET
    Токсичный шарпист
    Какой тип у ProductId? Если это Guid, то смотри какие у него конструкторы есть.
    Проще всего через Guid.Parse.

    PS:
    А DbContext мокать не нужно. Используй вместо этого EF Core inmemory, либо Sqlite с размещением в оперативной памяти.

    Будет что-то типа:
    var conn = new SqliteConnection("DataSource=:memory:");
    var options = new DbContextOptionsBuilder<ApplicationContext>()
       .UseSqlite(conn)
       .Options;
    
    using var dbContext = new ApplicationContext(options);
    dbContext.Products.Add(new Product { /*...*/});
    dbContext.SaveChanges();
    
    var controller = new CartController(dbContext);
    // ...


    PPS:
    Если ты хочешь тестировать контроллеры - значит ты что-то делаешь не так. Возможны два варианта:

    1. Ты наговнокодил и затолкал бизнес-логику в контроллеры.
    Если так, то выноси логику в сервисы и делай так, чтобы контроллер зависел от сервисов.

    2. Тебе на самом деле нужны интеграционные / api-тесты / e2e-тесты. В таком случае тебе нужно не контроллер конструировать, а поднимать сервер и тестировать при помощи http-запросов. В таком случае следует ещё и по пути полноценную СУБД поднимать, а не мок.
    Ответ написан
    6 комментариев
  • Как развернуть веб-приложение?

    vabka
    @vabka Куратор тега ASP.NET
    Токсичный шарпист
    Какая ОС должна быть установлена на сервере

    Если у тебя старый asp net, а не новый asp net core, то у тебя как минимум должна быть машина с Windows Server и IIS.

    Sql Server можно развернуть на ней же, а можно на линуксовой тачке - смотри что удобнее, в зависимости от имеющихся лицензий и компетенций админов.

    Если всё-таки asp net core, то можно развернуть на машине с Linux, например с Ubuntu. Для этого необходимо установить все зависимости (какие и как - написано в инструкции по установке на сайте MS). Для автоматического запуска при включении сервера и перезапуска при падении - заворачивай в systemd (нужно будет написать буквально 1 небольшой конфиг на десяток строчек - инструкции тоже есть в интернете)

    предоставить доступ к сайту не абсолютно всем пользователям в сети Интернет, а только филиалам предприятия

    Для этого, обычно, в рамках предприятия используют VPN - спроси у админов, вероятно он уже есть и они объяснят, как твой новый сервер в него внести. Они же помогут тебе прописать твой сервис в DNS.

    И как в данном случае приобретается доменное имя для поиска сайта, ведь в данном случае у предприятия собственный сервер и он не приобретает хостинг.

    Тк предполагается доступ только из сети предприятия - никакой домен приобретать не нужно.
    Всё прописывается в DNS предприятия.
    Ответ написан
    7 комментариев
  • Где находятся теги описанные в @{ }?

    vabka
    @vabka Куратор тега ASP.NET
    Токсичный шарпист
    Видимо Request.Method != POST
    Ответ написан
  • Стоит ли создавать таблицу в БД, в которой будет заведомо фиксированное кол-во записей?

    vabka
    @vabka Куратор тега ASP.NET
    Токсичный шарпист
    Я бы енам сделал (ещё лучше, если это енам из Pg)

    1. Не так уж и часто этот список меняться будет.
    2. Делать конверсию из значения енама в текст будет дешевле на стороне приложения, а не джоином.
    Ответ написан
    Комментировать
  • Как сделать деплой .net core в yandex.cloud serverless Container?

    vabka
    @vabka Куратор тега ASP.NET
    Токсичный шарпист
    Комментировать
  • Почему выводятся одно и то же значение несколько раз?

    vabka
    @vabka Куратор тега ASP.NET
    Токсичный шарпист
    Код на js сейчас на столько плохой и запутанный, что легче его полностью переписать, чем разбираться, что в нём не так.
    Больше всего у меня подозрений на странную функцию SubmitDataLinks и странное перекладывание данных из одного в другое в обработчике нажатия на кнопку
    Спойлер

    Перекладывание
    var storage = { // Зачем вообще такая табличная форма нужна?
                    Mname: [
                        { mname: "vk" },
                        { mname: "tg" },
                        { mname: "inst" },
                        { mname: "facebook" }
                    ],
                    Link: [
                        { link: val.vk },
                        { link: val.tg },
                        { link: val.inst },
                        { link: val.facebook }
                    ]
                }
                var storageForSubmit = { // Почему один и тот же объект постоянно перезаписывается?
                    Mname: "",
                    Link: ""
                }
                for (var i = 0; i < storage.Link.length; i++) {
                    storageForSubmit.Mname = storage.Mname[i].mname // А не проще было бы for-of сделать?
                    storageForSubmit.Link = storage.Link[i].link
    
                    form.append("Media", JSON.stringify(storageForSubmit))
                    SubmitDataLinks(storageForSubmit) // Вот сюда в итоге один и тот же объект будет отправляться
                }


    Отправка:
    function SubmitDataLinks(storageForSubmit) { // storageForSubmit даже не используется
                $(document).ready(function(){// зачем оно в .ready обёрнуто???
                    $.ajax({
                    type: "POST",
                    url: "@Url.Action("SaveFile")",
                    data: form, // Поведение при использовании FormData недокументировано
                    processData: false,
                    contentType: false, // Поведение при contentType=false недокументировано
                    success: function () {
                        console.log("Успешно!")
                    },
                    error: function () {
                        console.log("Ошибка!")
                    }
                })
                })
            }




    1. Меняем серверную часть:
    Контроллер:
    [HttpPost]
    public void SaveFile([FromBody] UploadMedia data)
    {
      Console.WriteLine(data);
    }


    UploadMedia:
    public record UploadMedia(string MediaName, string MediaLink);


    2. Меняем нафиг весь js:
    document.addEventListener('DOMContentLoaded', () => {
        const saveFileEndpoint = '@Url.Action("SaveFile")';
        const readLinks = () => ({
            "vk": document.querySelector("input.link-vk").value,
            "tg": document.querySelector("input.link-tg").value,
            "inst": document.querySelector("input.link-inst").value,
            "facebook": document.querySelector("input.link-facebook").value,
        })
    
        const submitLinks = async (links) => {
            for (const mediaWithLink of links) {
                await fetch(saveFileEndpoint, {
                    method: "POST",
                    body: JSON.stringify(mediaWithLink),
                    headers: {
                        "Content-Type": "application/json"
                    }
                })
            }
        }
    
        const onSaveLinks = async () => {
            const allLinks = readLinks();
            const linksList = Object.keys(allLinks).map(key => ({ "MediaName": key, "MediaLink": allLinks[key] }));
            try {
                await submitLinks(linksList);
                console.log("Ссылки сохранены");
            } catch (e) {
                console.error(`Произошла ошибка при отправке ссылок: ${e.message}`);
            }
        };
    
        document.querySelector("button.save-links").addEventListener("click", onSaveLinks);
    });
    Ответ написан
    Комментировать
  • Какую архитектуру использовать в ASP.NET Web API?

    vabka
    @vabka Куратор тега ASP.NET
    Токсичный шарпист
    В реальных проектах используют разные варианты исходя из личного опыта и настроения каждого члена команды на момент старта проекта.

    Может быть и супер сложный clean architecture + DDD + CQRS.
    Может быть Vertical Slice.
    А может быть и предельно простая архитектура даже без разделения на проекты (крайне недооценённый вариант на самом деле)

    У всего есть свои плюсы и минусы.
    Ответ написан
    Комментировать
  • Как добавлять новую страницу html на ASP.NET через админку?

    vabka
    @vabka Куратор тега ASP.NET
    Токсичный шарпист
    html - это текст.
    Тебе нужно добавить, видимо, какой-то свой редактор, чтобы пользователям было его удобно его редактировать, и добавить место, куда ты этот текст будешь сохранять (отдельную таблицу в базе например).

    Затем добавляешь какой-нибудь новый контроллер, у которого будет метод, который будет обрабатывать запросы вида GET something/{page_name} и будет находить нужную страницу по её page_name
    Ответ написан
    Комментировать
  • Как сделать мультиязнычость сайта?

    vabka
    @vabka Куратор тега ASP.NET
    Токсичный шарпист
    заводи отдельную таблицу для альтернативных языков.
    Пусть будет условно:
    id статьи - язык - текст
    Или
    id - тип(статья/другое) - язык - текст

    Соответственно фронт должен на бэк отправить ожидаемый язык контента, а бэк при сборке ответа - вытащить нужный перевод.
    Ответ написан
    Комментировать
  • Где можно хранить данные кроме БД?

    vabka
    @vabka Куратор тега ASP.NET
    Токсичный шарпист
    Никто не может тебе запретить хранить данные так, как ты хочешь.
    Вопрос исключительно удобства, надёжности, и допустимости.
    Ответ написан
    Комментировать
  • Как ускорить запуск ASP.NET MVC приложения?

    vabka
    @vabka Куратор тега ASP.NET
    Токсичный шарпист
    На IIS вполне можно реализовать сине-зелёные деплои, но нужно будет поавтоматизировать.
    Как пример:
    https://mthai.medium.com/setup-an-iis-blue-green-e...

    Ещё для ускорения запуска можно попробовать out-of-process и компилировать в ReadyToRun.
    А там можно и вообще с винды и веб-деплоя уехать.
    Ответ написан
    Комментировать
  • Есть ли в РФ недорогой хостинг для asp.net core в 2023 net 6.0?

    vabka
    @vabka Куратор тега ASP.NET
    Токсичный шарпист
    Проще всего разворачивать на VPS или в контейнерах.
    Не стоит искать хостинги специально для asp net
    Ответ написан
    Комментировать
  • Как лучше запускать проект asp.net на .net 7?

    vabka
    @vabka Куратор тега ASP.NET
    Токсичный шарпист
    Думаю, с http и https всё и так понятно.
    Обычно разницы нет, но иногда удобнее http если нельзя серты установить, а иногда https, когда он обязателен.

    WSL - запустит в WSL. Удобно если в итоге твоё приложение должно запускаться в линуксе и есть некоторая привязка к нему.

    IIS Express - запустит в iis express. имеет смысл, если деплоить потом будешь на IIS (лично я всегда этот пункт удаляю).
    Ответ написан
    5 комментариев
  • Обязательно ли добавлять службу и в builder и в app?

    vabka
    @vabka Куратор тега ASP.NET
    Токсичный шарпист
    AddCors - добавляет службу в IServiceCollection.
    UseCors - говорит аспнету, что нужно ещё добавить соответствующий middleware в конвеер обработки запроса.

    Так что да, обязательно.
    Если вызвать только AddCors - служба будет добавлена в контейнер, но никак не будет использоваться.
    Если вызвать только UseCors - во время конструирования конвеера возникнет исключение, тк aspnet не сможет получить необходимые зависимости.
    Ответ написан
    1 комментарий
  • Какие статьи почитать (или видео), чтобы разобраться полностью в теме про роутинг в .net?

    vabka
    @vabka Куратор тега ASP.NET
    Токсичный шарпист
    Ну варианта три:
    1. Конвенции
    2. Атрибуты
    3. MapGet / MapPost итд

    Это если не считать всякие сторонние роутеры типа F# Giraffe

    Атрибуты были и в .net framework.
    А от Convention based все уходят, тк:
    1. Не позволяет делать нормальный rest-style роутинг. Да и в принципе маршруты с ним получаются не очень красивые, и не очень предсказуемые.
    2. Легко может поломаться

    private static void MapEndpoint(

    Последнее - это частный случай 3го варианта. Ещё он есть в формате отдельной библиотеки - Carter
    Ответ написан
    2 комментария
  • Из за чего может не выводить в консоль dbug?

    vabka
    @vabka Куратор тега ASP.NET
    Токсичный шарпист
    Из за чего может не выводить в консоль dbug?

    Из-за того что у тебя явно в конфиге указаны минимальные уровни логирования (в твоём случае отрабатывает строчка Default: Information):
    "Logging": {
        "LogLevel": {
          "Default": "Information",
          "Microsoft.AspNetCore": "Warning",
          "Microsoft.EntityFrameworkCore": "Information"
        }
      }

    Уровни логирования такие, от самого высокого к самому низкому:
    • None = 6
    • Critical = 5
    • Error = 4
    • Warning = 3
    • Information = 2
    • Debug = 1
    • Trace = 0

    Как видишь, Information и Warning идут выше, чем Debug.
    Чтобы сообщение залогировалось - его уровень должен быть выше или равен минимальному уровню.

    https://learn.microsoft.com/ru-ru/dotnet/api/micro...
    Ответ написан
    Комментировать
  • В чем различия ASP.NET CORE 5 и ASP.NET CORE 6?

    vabka
    @vabka Куратор тега ASP.NET
    Токсичный шарпист
    Есть статья, которая буквально называется
    What's new in ASP.NET Core 6.0
    Ответ написан
    Комментировать