【发布时间】:2021-04-16 11:55:03
【问题描述】:
我正在尝试处理 webapi 中服务部分的异常。 我试图实现的目标是:
当服务出现错误时,例如when didn't find the todo with certain id 控制器应该返回带有自定义状态码的自定义 json 响应。
因为在我的项目中控制器和服务是分开的,不知道如何实现它。
提前致谢。
在我的代码下面:
在Services/TodoRepository.cs
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using test.Data;
using test.DTO;
using test.Interfaces;
using test.Models;
namespace test.Services
{
public class TodoRepository : ITodoRepository
{
private readonly DataContext _context;
public TodoRepository(DataContext context)
{
_context = context;
}
public async Task<IEnumerable<Todo>> GetTodosAsync()
{
return await _context.Todos.ToListAsync();
}
public async Task<Todo> GetTodoAsync(int id)
{
return await _context.Todos.FindAsync(id);
}
public async Task<Todo> AddTodoAsync(TodoInput input)
{
var todo = new Todo
{
Title = input.Title,
Description = input.Description,
IsDone = input.IsDone
};
await _context.Todos.AddAsync(todo);
return todo;
}
public async Task<Todo> SetTodoAsync(int id, TodoInput input)
{
var todo = await _context.Todos.FindAsync(id);
if (todo == null)
//
// CONTROLLER SHOULD RETURN CUSTOM
// JSON RESPONSE WITH CUSTOM STATUS CODE
// INSTEAD OF EXCEPTION WITH INTERNAL SERVER ERROR
//
throw new Exception("Could not find an item with this id");
todo.Title = input.Title;
todo.Description = input.Description;
todo.IsDone = input.IsDone;
todo.Updated = DateTime.Now;
_context.Todos.Update(todo);
return todo;
}
public async Task<Todo> DeleteTodoAsync(int id)
{
var todo = await _context.Todos.FindAsync(id);
if (todo == null)
//
// CONTROLLER SHOULD RETURN CUSTOM
// JSON RESPONSE WITH CUSTOM STATUS CODE
// INSTEAD OF EXCEPTION WITH INTERNAL SERVER ERROR
//
throw new Exception("Could not find an item with this id");
_context.Todos.Remove(todo);
return todo;
}
public async Task<bool> SaveAllAsync()
{
return await _context.SaveChangesAsync() > 0;
}
}
}
在Controllers/TodosController.cs
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using test.Data;
using test.DTO;
using test.Interfaces;
using test.Models;
namespace test.Controllers
{
[ApiController]
[Route("[controller]")]
public class TodosController : ControllerBase
{
private readonly DataContext _context;
private ITodoRepository _repository;
public TodosController(DataContext context, ITodoRepository repository)
{
_context = context;
_repository = repository;
}
[HttpGet]
public async Task<ActionResult<IEnumerable<Todo>>> GetTodos()
{
return Ok(await _repository.GetTodosAsync());
}
[HttpGet("{id}")]
public async Task<ActionResult<Todo>> GetTodo([FromRoute] int id)
{
return Ok(await _repository.GetTodoAsync(id));
}
[HttpPost]
public async Task<ActionResult<Todo>> AddTodo([FromBody] TodoInput input)
{
var todo = await _repository.AddTodoAsync(input);
if (!await _repository.SaveAllAsync())
return BadRequest("something gone wrong");
return Ok(todo);
}
[HttpPut("{id}")]
public async Task<ActionResult<Todo>> SetTodo([FromRoute] int id, [FromBody] TodoInput input)
{
var todo = await _repository.SetTodoAsync(id, input);
if (!await _repository.SaveAllAsync())
return BadRequest("something gone wrong");
return Ok(todo);
}
[HttpDelete("{id}")]
public async Task<ActionResult<Todo>> DeleteTodo([FromRoute] int id)
{
var todo = await _repository.DeleteTodoAsync(id);
if (!await _repository.SaveAllAsync())
return BadRequest("something gone wrong");
return Ok(todo);
}
}
}
【问题讨论】:
标签: c# asp.net-core asp.net-web-api