在Controller Asp net .core中添加文章

问题描述 投票:0回答:1

我想从我的控制器添加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>();

有人可以帮助你理解为什么它不起作用?

c# asp.net asp.net-core .net-core
1个回答
1
投票

没有实际的例外情况,不可能完全帮助你。但是,以下行尖叫“错误”:

if (author.Id != int.Parse(User.FindFirst(ClaimTypes.NameIdentifier).Value))

你有一个潜在的NullReferenceExceptionFormatExceptionArgumentNullException都来自那一行。

首先,您的控制器和动作都没有用Authorize属性装饰,并且您没有提供有关您正在进行的请求的信息,以及您是否甚至包括类似于Authorization标题的内容,以及您是否'你有没有在Startup.cs中正确配置身份验证以利用它。无论多头还是空头,实际上没有用户委托人可以从一开始就获得索赔。

每当你有一些可能为null的东西(比如从User.FindFirst返回)时,你应该进行空检查。这可能是一个真正的if语句或三元,null-coalesce(??),或更新的null-conditional(?.)。否则,如果您尝试访问一个恰好为null的实例的成员,您将获得一个NullReferenceException抛出。对于这个实际上,你可以做的最好的事情就是使用User.FindFirstValue代替,然后不需要取消引用Value成员。

接下来,如果FindFirstValue的回归最终成为nullint.Parse将抛出ArgumentNullException,因为你无法解析nullint。因此,在调用此值之前,您需要确保该值不为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()

© www.soinside.com 2019 - 2024. All rights reserved.