CastError:模型“customer”的路径“_id”中的值“customers”转换为 ObjectId 失败

Posted

技术标签:

【中文标题】CastError:模型“customer”的路径“_id”中的值“customers”转换为 ObjectId 失败【英文标题】:CastError: Cast to ObjectId failed for value "customers" at path "_id" for model "customer" 【发布时间】:2021-01-17 19:37:27 【问题描述】:

我希望有人能帮我弄清楚我在这里做错了什么。我一直在寻找,我可以找到很多类似的问题,但没有什么我足够聪明来解决我的问题。我收到以下错误:

它以前可以工作,但我设法破坏了它,我撤消了我认为我改变的所有东西,但我仍然收到错误。

这是我的架构:

const Schema = mongoose.Schema;

const CustomerSchema = new Schema(

  custName: 
    type: String,
    required: true
  ,
  custStreet: 
    type: String
  ,
  custCity: 
    type: String
  ,
  custState: 
    type: String
  ,
  custZip: 
    type: String
  
);

module.exports = Customer = mongoose.model('customer', CustomerSchema); 

我的路线:

const router = express.Router();

const customerController = require('../../controllers/customer')

const Customer = require('../../models/Customer');

router.route('/')
  .get(customerController.index)
  .post(customerController.newCustomer);

router.route('/:customerID')
  .get(customerController.getCustomer)

module.exports = router;

还有我的控制器:


module.exports = 

  index: async (req, res, next) => 
    try 
    const customers = await Customer.find()
    res.status(200).json(customers);
   catch(err) 
      next(err);
    
  ,

  newCustomer: async (req, res, next) => 
    try 
    const newCustomer = await Customer(req.body);
    const customer = await newCustomer.save();
    res.status(201).json(customer);
       catch(err) 
          next(err);
      
  , 

  getCustomer: async(req, res, next) => 
    try 
    const  customerID  = req.params;
    const customer= await Customer.findById(customerID);
    res.status(200).json(customer);  
     catch(err) 
        next(err);
    
  
;

另外,这是我得到的全部信息:

在 model.Query.exec (C:\Users\natha\Desktop\Coding\HAMMER\node_modules\mongoose\lib\query.js:4371:21) 在 model.Query.Query.then (C:\Users\natha\Desktop\Coding\HAMMER\node_modules\mongoose\lib\query.js:4463:15) 在 processTicksAndRejections (internal/process/task_queues.js:93:5)

还有一些让我感到困惑的事情,我的数据库中有另一个路由文件和控制器用于另一个集合。它基本上是相同的代码,除了路由到'/:Customers'而不是路由到'/:Tickets'并且它工作得很好。我看不出这段代码是如何工作的,Customers 代码不是。

路线:

const router = express.Router();

const ticketController = require('../../controllers/ticket');

router.route('/')
  .get(ticketController.index)
  .post(ticketController.newTicket);

router.route('/:ticketID')
  .get(ticketController.getTicket)
  .put(ticketController.replaceTicket)
  .patch(ticketController.updateTicket);

module.exports = router;

控制器:


module.exports = 

 index: async(req, res, next) => 
   try 
     const tickets = await Ticket.find()
     res.status(200).json(tickets);
    catch(err) 
     next(err);
   
 ,

 newTicket: async (req, res, next) => 
   try 
     const newTicket = await Ticket(req.body);
     const ticket = await newTicket.save();
     res.status(201).json(ticket);
    catch(err) 
      next(err);
   
 ,

 getTicket: async(req, res, next) => 
  try 
  const  ticketID  = req.params;
  const ticket = await Ticket.findById(ticketID);
  res.status(200).json(ticket);
   catch(err) 
      next(err);
  
 , 

 replaceTicket: async(req, res, next) =>
   try 
     const  ticketID  = req.params;
     const newTicket = req.body;
     const result = await Ticket.findByIdAndUpdate(ticketID, newTicket);
     res.status(200).json( Success: true );
    catch(err) 
      next(err);
   
 ,

 updateTicket: async(req, res, next) =>
   try 
     const  ticketID  = req.params;
     const newTicket = req.body;
     const result = await Ticket.findByIdAndUpdate(ticketID, newTicket);
     res.status(200).json( Success: true );
    catch(err) 
      next(err);
   
  
;

如果有任何帮助,我将不胜感激!

谢谢

-N8

【问题讨论】:

【参考方案1】:

我发现了问题。我的 server.js 文件中有这个:

app.use('/', customers);
app.use('/customers', customers);
app.use('/materials', materials)
app.use('/tickets', tickets)

一旦我摆脱了app.use('/', customers);,一切都很好。

【讨论】:

【参考方案2】:

getCustomer 处理程序中有错误。

您不应该使用字符串 id 来查找客户,而必须先使用 mongoose.Types.ObjectId(STRING_ID)

getCustomer: async(req, res, next) => 
    try 
    const  customerID  = req.params;
    const customer= await Customer.findById(mongoose.Types.ObjectId(customerID));
    res.status(200).json(customer);  
     catch(err) 
        next(err);
    
  

【讨论】:

感谢您的回复!所以,我的getCustomer 似乎可以正常工作,我根据您的建议进行了编辑,getCustomer 仍然有效。运行index 时出现错误。奇怪的是,如果我在路由文件'.get(customerController.getCustomer)` 中注释掉以下行,那么index 工作正常。但是当我取消注释'index'停止工作并且'getCustomer'工作正常。 @Nate 在index handler中,可以去掉空对象条件,然后再试试。 删除空的 的结果相同。如果.get(customerController.getCustomer) 被注释掉,则索引处理程序起作用。如果它没有被注释掉,getCustomer 处理程序就可以工作。【参考方案3】:

我赞成 OP 的解决方案。为了节省大量时间,我只想解释为什么这是一个问题以及其他人可以像我一样注意什么。所以在 OP server.js 中,'/' 出现在其他违反规则以列出特定路由的路由之前第一的。意思是,如果在解决其他路由问题后移动了“/”。 更重要的是,这个错误来自哪里?当您调用任何其他路由时,您的应用首先调用“/”并使用客户的路由,同时将路由路径(即“/customers”、“/materials”、“/tickets”)作为 id 参数传递,然后是 mongo正在尝试将客户、材料和票证作为客户集合中的 id。

app.use('/customers', customers);
app.use('/materials', materials)
app.use('/tickets', tickets)
app.use('/', customers);

这将解决 OP 的问题。

就我而言,这就是问题所在:

router.get('/', getAllUser);
router.get('/:id', getUserById)
router.get('/facebook', facebookPassport)
router.get('/google', customersPassport);

所以在这里我得到了这个错误模型用户路径“_id”处值“facebook”/“google”的转换错误因为字符串“facebook”和最后两个路由中的“google”是特定的,但永远不会到达,因为 '/:id' 路由将接受 '/' 之后的任何值作为 id。当我像这样重新排列时:

router.get('/', getAllUser);
router.get('/facebook', facebookPassport)
router.get('/google', customersPassport);
router.get('/:id', getUserById)

Take away:在应用级别和路由文件中将特定路由移动到动态路由(带有参数的路由)的顶部。

【讨论】:

为了让你的答案更清晰、更容易理解,我建议你也为你的建议添加一个代码范例。 感谢@EvanP,我添加了一些代码上下文。我希望它会非常有帮助,并且可以避免有人因为模型错误而疯狂追逐。

以上是关于CastError:模型“customer”的路径“_id”中的值“customers”转换为 ObjectId 失败的主要内容,如果未能解决你的问题,请参考以下文章

CastError:对于猫鼬中模型的路径“_id”处的值“findByName”,转换为 ObjectId 失败

CastError:对于猫鼬中模型的路径“_id”处的值“findByName”,转换为 ObjectId 失败

CastError:模型“Company”的路径“_id”处的值“...”转换为 ObjectId 失败

CastError:模型“Company”的路径“_id”处的值“...”转换为 ObjectId 失败

CastError:模型的路径“_id”处的值“:id”转换为 ObjectId 失败

Mongoose:CastError:对于模型“”的路径“_id”处的值“”,转换为 ObjectId 失败