【问题标题】:Add Article in Controler Asp net .core在控制器 Asp net .core 中添加文章
【发布时间】:2018-08-31 21:35:47
【问题描述】:

我正在尝试从我的控制器添加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>();

有人可以帮助您了解为什么它不起作用吗?

【问题讨论】:

  • 欢迎来到stackoverflow!是抛出异常还是看到某种错误消息?
  • 请提供有关您收到的错误的更多详细信息。
  • 可能只是在您的操作CretaArticle 上添加一个“[HttpPost]”。您能提供如何将数据发布到服务器吗?

标签: c# asp.net asp.net-core .net-core


【解决方案1】:

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

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

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

首先,您的控制器和操作都没有使用Authorize 属性进行修饰,并且您没有提供有关您正在发出的请求的信息,以及您是否包含类似Authorization 标头的信息有了这个,也没有你是否在Startup.cs 中正确配置了身份验证来使用它,有吗?总而言之,很可能一开始就没有用户主体来获得索赔。

任何时候你有可能为空的东西(比如来自User.FindFirst的返回),你应该做一个空检查。这可能是一个实际的 if 语句或三元、空合并 (??) 或更新的空条件 (?.)。否则,如果您尝试访问碰巧为空的实例的成员,您将收到NullReferenceException 抛出。为此,您实际上可以做的最好的事情就是简单地使用 User.FindFirstValue 代替,这样就无需在之后取消引用 Value 成员。

接下来,如果FindFirstValue 的返回结果是nullint.Parse 将抛出ArgumentNullException,因为您无法将null 解析为int。因此,您需要在调用它之前确保该值不为空。

然后,如果 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()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-06-25
    • 1970-01-01
    • 2022-07-27
    • 1970-01-01
    • 2018-01-29
    • 1970-01-01
    • 2020-10-03
    • 1970-01-01
    相关资源
    最近更新 更多