Ответы пользователя по тегу ASP.NET
  • Как сгенерировать 404 из view в asp.net core?

    NikFaraday
    @NikFaraday
    Student full-stack Developer
    В asp.net core ЧТО? Blazor Server? Blazor Web Assembly? Razor Pages? Web Api?

    Какие исключения? Вы понимаете, что такое исключение на уровне приложения? Это когда программа "отвалилась", произошла ошибка, сервер накрылся, базу данных физически украли, свет отключили или что-то подобное

    Ваш HttpException это по факту ошибка работы с протоколом Http, ошибка передачи информации или подобное. И то, даже школьники уже понимают, что ошибки нужно обрабатывать, а не специально генерировать. Если у вас программа будет на сервере, а вас просто сервер накроется из-за такого кода и вам нужно будет лезть и всё заново запускать

    Ошибка 404 это просто статус ответ от сервера, который уведомляет вас о том, что запрашиваемый ресурс не найден. Если у вас всё же стоит Web Api, тогда просто в контроллере делаете return NotFound()

    Если у вас Razor Pages или MVC, просто сделайте return RedirectToAction("NotFound", "Home") предварительно создав страницу NotFound в контроллере Home
    Ответ написан
    4 комментария
  • По какой причине User равен null?

    NikFaraday
    @NikFaraday
    Student full-stack Developer
    Нужен дебаг-скрин контекста при запросе. Скорее всего у вас просто неверный заголовок либо его значение
    Ответ написан
  • От чего появляется 405 http code?

    NikFaraday
    @NikFaraday
    Student full-stack Developer
    Если у вас экшен (endpoint) на сервере помечен как HttpGet, а вы отправляете HttpPost запрос. Наоборот так же работает, если отправляете HttpGet запрос на эндпоин, который принимает HttpPost запросы.

    Либо если вы пытаетесь отправить запрос куда-то, где нет принимающего экшена. В вашем случае, после билда формы, у вас не указал экшен. Значит запрос отправляется на стандартынй роут контроллера, на котором у вас нет экщена.

    Второй момент, не используйте для отправки формы, это уже застарелая штука и не очень эффективная. Лучше используйте отправку через Java Script или Ajax

    Ещё UPD. Вы указываете роут для вашего эндпоинты. Если вы используете asp.net core MVC, лучше его убрать, т.к. он вам не нужен для отправки через форму. Скорее всего именно эта штука и сбивает отправку
    Ответ написан
    Комментировать
  • В каких случаях создавать новые контроллеры?

    NikFaraday
    @NikFaraday
    Student full-stack Developer
    Если вы работаете с Entity Framework, возьмите себе правило "Одна Entity - Один Controller". Потом сюда можете добавлять контроллеры для логических единиц в виде следующих:
    • Авторизация. Для подобных действий в системе всегда должен использоваться отдельный контроллер. Регистрация, вход в систему, выход из системы, проверка существования пользователя, получить текущего авторизированного пользователя и т.д.
    • Файлы. Загрузить, удалить, получить, конвертировать и т.д.
    • Статистика. Обновить статистику, получить и т.д.
    • Другие действия, действия с которыми не полностью покрывают взаимодействие с самой Entiy, а только лишь с некими данными, но таких действий может быть очень много (Для примера AuthenticationController)
    Ответ написан
    Комментировать
  • Как подружить MVC с реляционной базой данных?

    NikFaraday
    @NikFaraday
    Student full-stack Developer
    Как подружить MVC с реляционной базой данных?

    Та нормально они дружат через Entity Framework, Dapper либо другие ORM.

    Форма не может передать методу POST сложные типы

    А при чём тут ваш вопрос "Как подружить MVC с реляционной базой данных?", если вы не можете передать с клиента на сервер?

    ModelState требует, чтоб были заполнены и CountryId, и Country одновременно.

    Используйте модели. Просто создайте другой класс (Модель), который будете использовать для get/post запросов (По отдельности, одна модель - один запрос) и вынесите туда всё, что вам нужно. Обычно вам хватит только Id того объект с каким будете работать + поля, которые нужны для создания/обновления/добавления и т.д. Для удаления вам хватит просто Id, для обновления нужны только поля, которые нужно обновить и Id того объекта, который нужно обновлять. И будет вам работа с примитивами )

    Для валидации вообще рекомендую накатить какую-то библиотеку по типу Fluent Validation Api либо Regex (Приоритетно)
    Ответ написан
    Комментировать
  • Как получить текст ответа ASP Net Core API?

    NikFaraday
    @NikFaraday
    Student full-stack Developer
    Основным методом общения между клиентом и сервером являются Status Code. Зачем вам передавать точное описание, что там оно не нашло, если вы можете просто передавать 404 и клиент пусть сам генерирует себе ошибку.

    Вообще забудьте про этот бред return StatusCode. Есть нормальные методы StatusResult к которым относятся Ok(), BadRequest() и тот же NotFound(). В эти методы можете передавать какие-то мета-данные если вам нужно. Либо можете использовать Response.Headers. Но если вам прям очень-очень нужно впихнуть туда вот это вообще об ошибке, так что бы ваш сервер был на все руки мастер, можете сделать что-то типа такого:

    return NotFound(new { message = "Omg, Not Found!!!" });


    UPD:
    Как на клиенте через JS вытянуть ошибку? Я бы использовал просто ajax:

    $.ajax({
        url: '...',
        method: 'get',
        success: (response): {
            let data = JSON.parse(response.responseText);
            console.log(data.message); //Omg, Not Found!!!
        }
    });
    Ответ написан
    3 комментария
  • Как сделать редирект на refresh-token когда получаю AuthenticationFailed на asp.net core web api?

    NikFaraday
    @NikFaraday Автор вопроса
    Student full-stack Developer
    Решил. Как это всё делается? Внутрь onAuthenticationFailed вставляем этот код:
    if (context.Exception?.GetType() == typeof(SecurityTokenExpiredException))
    {
        IJwtService jwtService = context.HttpContext.RequestServices.GetService<IJwtService>();
    
        if (context.Request.Cookies.TryGetValue("refresh-token", out string refreshToken))
        {
            Result<ClaimsPrincipal> principalResult = jwtService.ValidateAndDecodeToken(refreshToken);
            if (!principalResult.IsSuccess || principalResult.Value == null)
            {
                return Task.CompletedTask;
            }
    
            Result<string> renewAccessTokenResult = jwtService.Encode(principalResult.Value);
            if (!renewAccessTokenResult.IsSuccess && renewAccessTokenResult.ValidationErrors.Any())
            {
                return Task.CompletedTask;
            }
    
            context.Response.Cookies.Append("access-token", renewAccessTokenResult.Value);
            context.Response.StatusCode = 200;
            context.HttpContext.User = principalResult.Value;
            context.Principal = principalResult.Value;
            context.Success();
        }
    }
    return Task.CompletedTask;


    Т.е.. вызывает сервис, берём refresh token и из него извлекаем ClaimPrincipal, далее на его основе делаем access token из того же сервиса и обрабатываем запрос, что бы он возвращал нужный статус. Как говорил Andrei SunnyPh , это допустимая практика (Спасибо)
    Ответ написан
    Комментировать
  • Как развернуть сайт на asp.net?

    NikFaraday
    @NikFaraday
    Student full-stack Developer
    1. Делаете паблиш проекта
    2. Выбираете целевую ОС
    3. Делаете коннект на сервер
    4. Заливаете туда то, что у вас получилось в результате Паблиша через FileZilla
    5. Настраиваете сервис .net приложения
    6. Настраиваете nginx, что бы сервер постоянно работал
    7. Запускаете сам сервис приложения
    Ответ написан
    2 комментария
  • Как управлять локализацией дат?

    NikFaraday
    @NikFaraday
    Student full-stack Developer
    Вы можете использовать DatetimeOffset в связке с регистрацией локализации в Dependency Injection и Middleware
    Ответ написан
    Комментировать
  • Почему при навигации между компонентами в Blazor не погружается JS код?

    NikFaraday
    @NikFaraday
    Student full-stack Developer
    В blazor использовать кастомные JS скрипты немного сложнее чем вы думаете. Там нужно использовать такую штуку как JSRuntime. А вообще советую прочитать эту статью про JS Interop
    Ответ написан
    Комментировать
  • Как использовать аттрибут for для частичного предстваления asp.net core?

    NikFaraday
    @NikFaraday
    Student full-stack Developer
    Да, только вам для этого нужно юзать эту конструкцию:

    @await Html.PartialAsync("_partialNameWithoutExtension", new ModelForPartialView())
    Ответ написан
  • Как получить доступ к wwwroot из другого проекта в web api?

    NikFaraday
    @NikFaraday Автор вопроса
    Student full-stack Developer
    Конкретно в моём проекте оказало, что папки wwwroot вообще не существовало. Под капотом метод вообще не отрабатывал
    Directory.CreateDirector(...)

    Папку создал вручную в корне проекта, всё заработало.
    Ответ написан
    Комментировать
  • Почему fetch отдаёт 401 при JWT авторизации на сервер asp.net core web api?

    NikFaraday
    @NikFaraday Автор вопроса
    Student full-stack Developer
    Если вкратце, что и почему работает:


    1. Настройка CORS. Для того, что бы настроить cors для React(Next)JS Application, нужно указывать адрес https и это важно, поскольку при запуске приложения React(Next)JS адрес начинается с http. Пример:
      // ...
      services.AddCors(options =>
      {
          options.AddPolicy("AllowTeachToolClient",
              builder =>
              {
                  builder.WithOrigins("http://localhost:3000", "https://localhost:3000");
                  builder.AllowAnyHeader();
                  builder.AllowAnyMethod();
              });
      });
      // ...



    2. При генерации Jwt токена, нужно использовать именно SymmetricSecurityKey. Это для тех, кто захочет аналогично как я попробовать использовать что-то типа RSA(2048)

      Я не говорю, что они не работают, просто для начала с этим могут быть проблемы с реализацией



    3. Самое главное это заголовки. Лично у меня проблема решилась при наличии следующих header'ов:
      • Get:
        'Accept': '*/*',
        'Host': 'http://localhost:3000',
        'Content-Type': 'application/json',
        'Authorization': 'Bearer {token}'



      • Post:
        'Accept': '*/*',
        'Host': "http://localhost:3000",
        'Content-Type': 'application/json;'



        Понятно, что наличие заголовка
      Authorization зависит от того, куда кидаете запрос. Обычно используется, для доступа к [Authorize] контроллерам/эндпоинтам



    4. Настройка Cors (Нюанс, для тех, кто с таким может столкнуться). Код для регистрации политики Cors:
      services.AddCors(options =>
      {
          options.AddPolicy("AllowTeachToolClient",
              builder =>
              {
                  builder.WithOrigins("http://localhost:3000");
                  builder.AllowAnyHeader();
                  builder.AllowAnyMethod();
              });
      });


      И самое главное, что ниже эту же политику нужно подключить перед тем, как вы будете использовать app.UseAuthentication(); и app.UseAuthorization();. Вырезка с самого вопроса:

      var app = builder.Build();
      
      app.UseCors("AllowTeachToolClient");
      
      app.UseHttpsRedirection();
      
      app.UseAuthentication();
      app.UseAuthorization();
      
      app.MapControllers();
      
      app.Run();



    Ответ написан
    Комментировать
  • Как передать массив FormData через ajax?

    NikFaraday
    @NikFaraday Автор вопроса
    Student full-stack Developer
    Методом тыка, спустя три дня перебора комбинаций методов нашёл один, который работает. Конечно, он меня не удовлетворил в силу способа отправки данных, но это, по крайней мере, работает

    let packagesForm = new FormData();
    for (let i = 0; i < packages.length; i++) {
        packagesForm.append(`vm[${i}].Image`, packages[i].Image);
        packagesForm.append(`vm[${i}].MeasureUnit`, packages[i].MeasureUnit);
        packagesForm.append(`vm[${i}].VolumeUnit`, packages[i].VolumeUnit);
        packagesForm.append(`vm[${i}].Volume`, packages[i].Volume);
        packagesForm.append(`vm[${i}].Price`, packages[i].Price);
        packagesForm.append(`vm[${i}].ProductId`, Number(response.id));
    }
    Ответ написан
    Комментировать
  • Как вывести изображение используя байтовый массив?

    NikFaraday
    @NikFaraday Автор вопроса
    Student full-stack Developer
    src="data:image;base64,@System.Convert.ToBase64String(Model.User.Avatar)"
    Ответ написан
    Комментировать
  • Как изменить Collation(на кириллицу) в EF Core?

    NikFaraday
    @NikFaraday
    Student full-stack Developer
    EF Core по стандарту должен поддерживать кириллицу, по крайней мере, у меня с этим проблем не было. В чём у вас проблема именно?

    UPD:
    Вот пример куска БД старого проекта. БД создана на том же EF Core без дополнительных махинаций с языком
    639df57ae1369632626921.png
    Ответ написан
  • Как добавить поддержку кириллицы в post method Swagger?

    NikFaraday
    @NikFaraday
    Student full-stack Developer
    Я так понял, вы отправляете json с клиента. Во первых, проверьте дебагом, как выглядит name перед отплавкой на сервер. Во вторых, проверьте дебагом, как выглядит name во время получения объекта на сервере. Третий этап - то, как name будет отправлено и сохранено в БД
    Ответ написан
    Комментировать
  • Можно ли используя синтаксис Razor получить значение атрибутов cshtml страницы?

    NikFaraday
    @NikFaraday Автор вопроса
    Student full-stack Developer
    Сделал по другому - через ajax, что бы не использовать Url.Action. Ниже привёл часть скрипта:

    buttons[i].onclick = () => {
            let buttonId = buttons[i].id.split('-')[1];
            let note = document.getElementById('note-' + buttonId).innerHTML;
            noteModal.innerHTML = note;
    
            $("#delete-note-btn").on('click', () => {
                let data = {
                    NoteId: buttonId,
                    ClientId: @Model.ClientId,
                };
    
                let jsonData = JSON.stringify(data);
    
                $.ajax({
                    url: '@Url.Action("Delete", "Note")',
                    method: 'post',
                    data: jsonData,
                    dataType: 'json',
                    contentType: 'application/json; charset=utf-8',
                    success: (response) => {
                        document.getElementById('modal-close-button').click();
                        setTimeout(() => {
                            location.reload();
                        }, 500);
                    },
                    error: (response) => {
                        // Autoredirect to error view
                    },
                });
            });
        }
    Ответ написан
    Комментировать
  • Как вывести список в представление по одному id?

    NikFaraday
    @NikFaraday
    Student full-stack Developer
    Попробуйте юзнуть .Where при выборке, куда передать лямбду с логическим условием, что бы проверить каждый элемент по внешнему ключу, подходит он или нет
    Ответ написан
    Комментировать