我想从我的控制器添加Article
。但它不起作用。当我使用邮递员时,我收到错误500
ServiceFilter(typeof(LogUserActivity))]
[Route("api/users/{userId}/[controller]")]
[ApiController]
public class ArticleController : ControllerBase
{
private readonly IPrmRepository _repo;
private readonly IMapper _mapper;
public ArticleController(IPrmRepository repo, IMapper mapper)
{
_mapper = mapper;
_repo = repo;
}
public async Task<IActionResult> CretaArticle(int userId, ArticleForCreation articleForCreation)
{
var author = await _repo.GetUser(userId, false);
//check autorization
if (author.Id != int.Parse(User.FindFirst(ClaimTypes.NameIdentifier).Value))
return Unauthorized();
articleForCreation.AuthorId = userId;
var article = _mapper.Map<Article>(articleForCreation);
_repo.Add(article);
if (await _repo.SaveAll())
{
//Mapp Data to return db
var articleToReturn = _mapper.Map<ArticleToReturnDto>(article);
return CreatedAtRoute("GetArticle", new {id = article.ArticleId}, articleToReturn);
}
throw new Exception("Creating the article failed on save");
}
负责数据库中模型的模型:
public class Article
{
public int ArticleId { get; set; }
public string Title { get; set; }
public string Content { get; set; }
public int AuthorId{get; set;}
public User Author { get; set; }
}
DTOS:
public class ArticleForCreation
{
public int AuthorId { get; set; }
public string Title { get; set; }
public string Content { get; set; }
}
public class ArticleToReturnDto
{
public int Id { get; set; }
public int AuthorId { get; set; }
public string Title { get; set; }
public string Content { get; set; }
}
AutomapperProfile将数据映射到数据库:
CreateMap<ArticleForCreation, Article>().ReverseMap();
CreateMap<Article, ArticleToReturnDto>();
有人可以帮助你理解为什么它不起作用?
没有实际的例外情况,不可能完全帮助你。但是,以下行尖叫“错误”:
if (author.Id != int.Parse(User.FindFirst(ClaimTypes.NameIdentifier).Value))
你有一个潜在的NullReferenceException
,FormatException
和ArgumentNullException
都来自那一行。
首先,您的控制器和动作都没有用Authorize
属性装饰,并且您没有提供有关您正在进行的请求的信息,以及您是否甚至包括类似于Authorization
标题的内容,以及您是否'你有没有在Startup.cs
中正确配置身份验证以利用它。无论多头还是空头,实际上没有用户委托人可以从一开始就获得索赔。
每当你有一些可能为null的东西(比如从User.FindFirst
返回)时,你应该进行空检查。这可能是一个真正的if
语句或三元,null-coalesce(??
),或更新的null-conditional(?.
)。否则,如果您尝试访问一个恰好为null的实例的成员,您将获得一个NullReferenceException
抛出。对于这个实际上,你可以做的最好的事情就是使用User.FindFirstValue
代替,然后不需要取消引用Value
成员。
接下来,如果FindFirstValue
的回归最终成为null
,int.Parse
将抛出ArgumentNullException
,因为你无法解析null
到int
。因此,在调用此值之前,您需要确保该值不为null。
然后,如果id实际上不是可以解析为int
的东西,例如GUID,那么你最终会抛出一个FormatException
。您可能知道它是一个int,但是您应该始终保护您的代码以防止将来发生潜在的变化。当你需要将字符串解析为int(或任何其他原始类型)时,你应该总是使用TryParse
:
if (int.TryParse(myString, out int i)
{
// you can now use `i` as the parsed int for whatever you need
}
无论长短,这是编写这行代码的更好方法:
if (!int.TryParse(User.FindFirstValue(ClaimTypes.NameIdentifier), out int id) || author.Id != id)
return Unauthorized();
基本上,如果声明值为null /无法解析为int或者它不等于作者的id,则返回Unauthorized()
。