在路径“_id”中,什么是Mongoose错误转换为ObjectId失败?

时间:2022-02-05 02:33:09

When sending a request to /customers/41224d776a326fb40f000001 and a document with _id 41224d776a326fb40f000001 does not exist, doc is null and I'm returning a 404:

当发送一个请求到/客户/41224d776a326fb40f000001和一个带有_id 41224d776a326fb40f000001的文档时,doc是空的,我返回的是404:

  Controller.prototype.show = function(id, res) {
    this.model.findById(id, function(err, doc) {
      if (err) {
        throw err;
      }
      if (!doc) {
        res.send(404);
      }
      return res.send(doc);
    });
  };

However, when _id does not match what Mongoose expects as "format" (I suppose) for example with GET /customers/foo a strange error is returned:

但是,当_id与Mongoose所期望的“格式”(我假设)不匹配时,会返回一个奇怪的错误:

CastError: Cast to ObjectId failed for value "foo" at path "_id".

CastError:在path“_id”中,Cast to ObjectId没有值“foo”。

So what's this error?

这个错误是什么?

10 个解决方案

#1


101  

Mongoose's findById method casts the id parameter to the type of the model's _id field so that it can properly query for the matching doc. This is an ObjectId but "foo" is not a valid ObjectId so the cast fails.

Mongoose的findById方法将id参数转换为模型的_id字段的类型,以便它能够正确地查询匹配的文档。这是一个目标,但是“foo”不是一个有效的目标,所以cast失败了。

This doesn't happen with 41224d776a326fb40f000001 because that string is a valid ObjectId.

这不会发生在41224d776a326fb40f000001中,因为该字符串是一个有效的目标。

One way to resolve this is to add a check prior to your findById call to see if id is a valid ObjectId or not like so:

解决这一问题的一种方法是在findById调用之前添加一个检查,以查看id是否是一个有效的ObjectId,或者不是这样:

if (id.match(/^[0-9a-fA-F]{24}$/)) {
  // Yes, it's a valid ObjectId, proceed with `findById` call.
}

#2


21  

Use existing functions for checking ObjectID.

使用现有的功能检查目标。

var mongoose = require('mongoose');
mongoose.Types.ObjectId.isValid('your id here');

#3


8  

Are you parsing that string as ObjectId?

您是否将该字符串解析为ObjectId?

Here in my application, what I do is:

在我的应用中,我所做的是:

ObjectId.fromString( myObjectIdString );

#4


3  

You can also use ObjectId.isValid like the following :

你也可以使用ObjectId。其有效性如下:

if (!ObjectId.isValid(userId)) return Error({ status: 422 })

#5


1  

 if(mongoose.Types.ObjectId.isValid(userId.id)) {
        User.findById(userId.id,function (err, doc) {
            if(err) {
                reject(err);
            } else if(doc) {
                resolve({success:true,data:doc});
            } else {
                reject({success:false,data:"no data exist for this id"})

            }
        });
        } else {
            reject({success:"false",data:"Please provide correct id"});
        }

best is to check validity

最好是检查有效性。

#6


0  

I went with an adaptation of the @gustavohenke solution, implementing cast ObjectId in a try-catch wrapped around the original code to leverage the failure of ObjectId casting as a validation method.

我使用了@gustavohenke解决方案的一个修改,实现了在原始代码包装的try-catch中实现cast ObjectId,以利用ObjectId转换失败作为验证方法。

Controller.prototype.show = function(id, res) {
  try {
    var _id = mongoose.Types.ObjectId.fromString(id);



    // the original code stays the same, with _id instead of id:

    this.model.findById(_id, function(err, doc) {
      if (err) {
        throw err;
      }
      if (!doc) {
        res.send(404);
      }
      return res.send(doc);
    });



  } catch (err) {
    res.json(404, err);
  }
};

#7


0  

OR you can do this

或者你也可以这么做。

var ObjectId = require('mongoose').Types.ObjectId; var objId = new ObjectId( (param.length < 12) ? "123456789012" : param );

var ObjectId =要求(“猫鼬”).Types.ObjectId;新目标(param)。长度< 12)?“123456789012”:param);

as mentioned here Mongoose's find method with $or condition does not work properly

如上所述,Mongoose的find方法有$or条件不能正常工作。

#8


0  

This is an old question but you can also use express-validator package to check request params

这是一个老问题,但是您也可以使用expressvalidator包来检查请求参数。

express-validator version 4 (latest):

express-validator第4版(最新):

validator = require('express-validator/check');

app.get('/show/:id', [

    validator.param('id').isMongoId().trim()

], function(req, res) {

    // validation result
    var errors = validator.validationResult(req);

    // check if there are errors
    if ( !errors.isEmpty() ) {
        return res.send('404');
    }

    // else 
    model.findById(req.params.id, function(err, doc) { 
        return res.send(doc);
    });

});

express-validator version 3:

express-validator版本3:

var expressValidator = require('express-validator');
app.use(expressValidator(middlewareOptions));

app.get('/show/:id', function(req, res, next) {

    req.checkParams('id').isMongoId();

    // validation result
    req.getValidationResult().then(function(result) {

        // check if there are errors
        if ( !result.isEmpty() ) {
            return res.send('404');
        }

        // else
        model.findById(req.params.id, function(err, doc) {
            return res.send(doc);
        });

    });

});

#9


0  

Always use mongoose.Types.ObjectId('your id')for conditions in your query it will validate the id field before running your query as a result your app will not crash.

总是使用mongoose.Types。ObjectId('your id')在查询条件下,它将在运行查询之前验证id字段,从而使应用程序不会崩溃。

#10


0  

I faced this issue because I was declaring the router as

我面临这个问题,因为我声明路由器为。

router.put('/:id', async (req, res) => {
   // code ....
}

and was updating the data with url i.e.

并使用url更新数据。

http://localhost:3000/id=5af584ebb62aae2fa8e406a2

After spending a long time I correct myself by removing id= as

在花费了很长时间之后,我通过删除id=来纠正自己。

the right way was:

正确的方法是:

http://localhost:3000/5af584ebb62aae2fa8e406a2

Now I am able to use findById() as

现在我可以使用findById()了。

let myModel = await Model.findById(req.params.id);

#1


101  

Mongoose's findById method casts the id parameter to the type of the model's _id field so that it can properly query for the matching doc. This is an ObjectId but "foo" is not a valid ObjectId so the cast fails.

Mongoose的findById方法将id参数转换为模型的_id字段的类型,以便它能够正确地查询匹配的文档。这是一个目标,但是“foo”不是一个有效的目标,所以cast失败了。

This doesn't happen with 41224d776a326fb40f000001 because that string is a valid ObjectId.

这不会发生在41224d776a326fb40f000001中,因为该字符串是一个有效的目标。

One way to resolve this is to add a check prior to your findById call to see if id is a valid ObjectId or not like so:

解决这一问题的一种方法是在findById调用之前添加一个检查,以查看id是否是一个有效的ObjectId,或者不是这样:

if (id.match(/^[0-9a-fA-F]{24}$/)) {
  // Yes, it's a valid ObjectId, proceed with `findById` call.
}

#2


21  

Use existing functions for checking ObjectID.

使用现有的功能检查目标。

var mongoose = require('mongoose');
mongoose.Types.ObjectId.isValid('your id here');

#3


8  

Are you parsing that string as ObjectId?

您是否将该字符串解析为ObjectId?

Here in my application, what I do is:

在我的应用中,我所做的是:

ObjectId.fromString( myObjectIdString );

#4


3  

You can also use ObjectId.isValid like the following :

你也可以使用ObjectId。其有效性如下:

if (!ObjectId.isValid(userId)) return Error({ status: 422 })

#5


1  

 if(mongoose.Types.ObjectId.isValid(userId.id)) {
        User.findById(userId.id,function (err, doc) {
            if(err) {
                reject(err);
            } else if(doc) {
                resolve({success:true,data:doc});
            } else {
                reject({success:false,data:"no data exist for this id"})

            }
        });
        } else {
            reject({success:"false",data:"Please provide correct id"});
        }

best is to check validity

最好是检查有效性。

#6


0  

I went with an adaptation of the @gustavohenke solution, implementing cast ObjectId in a try-catch wrapped around the original code to leverage the failure of ObjectId casting as a validation method.

我使用了@gustavohenke解决方案的一个修改,实现了在原始代码包装的try-catch中实现cast ObjectId,以利用ObjectId转换失败作为验证方法。

Controller.prototype.show = function(id, res) {
  try {
    var _id = mongoose.Types.ObjectId.fromString(id);



    // the original code stays the same, with _id instead of id:

    this.model.findById(_id, function(err, doc) {
      if (err) {
        throw err;
      }
      if (!doc) {
        res.send(404);
      }
      return res.send(doc);
    });



  } catch (err) {
    res.json(404, err);
  }
};

#7


0  

OR you can do this

或者你也可以这么做。

var ObjectId = require('mongoose').Types.ObjectId; var objId = new ObjectId( (param.length < 12) ? "123456789012" : param );

var ObjectId =要求(“猫鼬”).Types.ObjectId;新目标(param)。长度< 12)?“123456789012”:param);

as mentioned here Mongoose's find method with $or condition does not work properly

如上所述,Mongoose的find方法有$or条件不能正常工作。

#8


0  

This is an old question but you can also use express-validator package to check request params

这是一个老问题,但是您也可以使用expressvalidator包来检查请求参数。

express-validator version 4 (latest):

express-validator第4版(最新):

validator = require('express-validator/check');

app.get('/show/:id', [

    validator.param('id').isMongoId().trim()

], function(req, res) {

    // validation result
    var errors = validator.validationResult(req);

    // check if there are errors
    if ( !errors.isEmpty() ) {
        return res.send('404');
    }

    // else 
    model.findById(req.params.id, function(err, doc) { 
        return res.send(doc);
    });

});

express-validator version 3:

express-validator版本3:

var expressValidator = require('express-validator');
app.use(expressValidator(middlewareOptions));

app.get('/show/:id', function(req, res, next) {

    req.checkParams('id').isMongoId();

    // validation result
    req.getValidationResult().then(function(result) {

        // check if there are errors
        if ( !result.isEmpty() ) {
            return res.send('404');
        }

        // else
        model.findById(req.params.id, function(err, doc) {
            return res.send(doc);
        });

    });

});

#9


0  

Always use mongoose.Types.ObjectId('your id')for conditions in your query it will validate the id field before running your query as a result your app will not crash.

总是使用mongoose.Types。ObjectId('your id')在查询条件下,它将在运行查询之前验证id字段,从而使应用程序不会崩溃。

#10


0  

I faced this issue because I was declaring the router as

我面临这个问题,因为我声明路由器为。

router.put('/:id', async (req, res) => {
   // code ....
}

and was updating the data with url i.e.

并使用url更新数据。

http://localhost:3000/id=5af584ebb62aae2fa8e406a2

After spending a long time I correct myself by removing id= as

在花费了很长时间之后,我通过删除id=来纠正自己。

the right way was:

正确的方法是:

http://localhost:3000/5af584ebb62aae2fa8e406a2

Now I am able to use findById() as

现在我可以使用findById()了。

let myModel = await Model.findById(req.params.id);