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
endpoint
) на сервере помечен как HttpGet
, а вы отправляете HttpPost
запрос. Наоборот так же работает, если отправляете HttpGet
запрос на эндпоин, который принимает HttpPost
запросы.Java Script
или Ajax
asp.net core MVC
, лучше его убрать, т.к. он вам не нужен для отправки через форму. Скорее всего именно эта штука и сбивает отправку Entity Framework
, возьмите себе правило "Одна Entity
- Один Controller
". Потом сюда можете добавлять контроллеры для логических единиц в виде следующих:Entiy
, а только лишь с некими данными, но таких действий может быть очень много (Для примера AuthenticationController
)Как подружить MVC с реляционной базой данных?
Форма не может передать методу POST сложные типы
ModelState требует, чтоб были заполнены и CountryId, и Country одновременно.
get/post
запросов (По отдельности, одна модель - один запрос) и вынесите туда всё, что вам нужно. Обычно вам хватит только Id того объект с каким будете работать + поля, которые нужны для создания/обновления/добавления и т.д. Для удаления вам хватит просто Id, для обновления нужны только поля, которые нужно обновить и Id того объекта, который нужно обновлять. И будет вам работа с примитивами )Fluent Validation Api
либо Regex
(Приоритетно) Status Code
. Зачем вам передавать точное описание, что там оно не нашло, если вы можете просто передавать 404
и клиент пусть сам генерирует себе ошибку.return StatusCode
. Есть нормальные методы StatusResult
к которым относятся Ok()
, BadRequest()
и тот же NotFound()
. В эти методы можете передавать какие-то мета-данные если вам нужно. Либо можете использовать Response.Headers
. Но если вам прям очень-очень нужно впихнуть туда вот это вообще об ошибке, так что бы ваш сервер был на все руки мастер, можете сделать что-то типа такого:return NotFound(new { message = "Omg, Not Found!!!" });
JS
вытянуть ошибку? Я бы использовал просто ajax
:$.ajax({
url: '...',
method: 'get',
success: (response): {
let data = JSON.parse(response.responseText);
console.log(data.message); //Omg, Not Found!!!
}
});
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 , это допустимая практика (Спасибо) // ...
services.AddCors(options =>
{
options.AddPolicy("AllowTeachToolClient",
builder =>
{
builder.WithOrigins("http://localhost:3000", "https://localhost:3000");
builder.AllowAnyHeader();
builder.AllowAnyMethod();
});
});
// ...
SymmetricSecurityKey
. Это для тех, кто захочет аналогично как я попробовать использовать что-то типа RSA(2048)Я не говорю, что они не работают, просто для начала с этим могут быть проблемы с реализацией
'Accept': '*/*',
'Host': 'http://localhost:3000',
'Content-Type': 'application/json',
'Authorization': 'Bearer {token}'
'Accept': '*/*',
'Host': "http://localhost:3000",
'Content-Type': 'application/json;'
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();
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));
}
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
},
});
});
}