mongodb - español - mongoose schema
¿Qué es el error Mongoose Cast para ObjectId falló para el valor XXX en la ruta "_id"? (10)
Al enviar una solicitud a /customers/41224d776a326fb40f000001
y no existe un documento con _id
41224d776a326fb40f000001
, doc
es null
y estoy devolviendo un 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);
});
};
Sin embargo, cuando _id
no coincide con lo que Mongoose espera como "formato" (supongo), por ejemplo, con GET /customers/foo
se devuelve un error extraño:
CastError: Cast to ObjectId falló para el valor "foo" en la ruta "_id".
Entonces, ¿qué es este error?
¿Estás analizando esa cadena como ObjectId
?
Aquí en mi aplicación, lo que hago es:
ObjectId.fromString( myObjectIdString );
El método findById
de findById
arroja el parámetro id
al tipo del campo _id
del modelo para que pueda consultar adecuadamente el documento correspondiente. Este es un ObjectId pero "foo"
no es un ObjectId válido, por lo que el molde falla.
Esto no ocurre con 41224d776a326fb40f000001
porque esa cadena es un ObjectId válido.
Una forma de resolver esto es agregar un cheque antes de su llamada findById
para ver si id
es un ObjectId válido o no, así:
if (id.match(/^[0-9a-fA-F]{24}$/)) {
// Yes, it''s a valid ObjectId, proceed with `findById` call.
}
Esta es una pregunta antigua pero también puede usar el paquete express-validator para verificar los parámetros de solicitud
express-validator versión 4 (última):
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);
});
});
expreso-validador versión 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);
});
});
});
Fui con una adaptación de la solución @gustavohenke, implementando ObjectId de lanzamiento en un try-catch envuelto alrededor del código original para aprovechar la falla de la conversión de ObjectId como método de validación.
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);
}
};
Me enfrenté a este problema porque estaba declarando el enrutador como
router.put(''/:id'', async (req, res) => {
// code ....
}
y estaba actualizando los datos con url ie
http://localhost:3000/id=5af584ebb62aae2fa8e406a2
Después de pasar mucho tiempo, me corrijo quitando id=
como
el camino correcto fue:
http://localhost:3000/5af584ebb62aae2fa8e406a2
Ahora puedo usar findById()
como
let myModel = await Model.findById(req.params.id);
O puedes hacer esto
var ObjectId = require(''mongoose'').Types.ObjectId; var objId = new ObjectId( (param.length < 12) ? "123456789012" : param );
como se menciona aquí, el método de búsqueda de Mongoose con $ o condición no funciona correctamente
Siempre use mongoose.Types.ObjectId(''your id'')
para las condiciones en su consulta, validará el campo de ID antes de ejecutar su consulta, como resultado, su aplicación no se bloqueará.
También puede usar ObjectId.isValid de la siguiente manera:
if (!ObjectId.isValid(userId)) return Error({ status: 422 })
Use las funciones existentes para verificar ObjectID.
var mongoose = require(''mongoose'');
mongoose.Types.ObjectId.isValid(''your id here'');
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"});
}
lo mejor es verificar la validez