Lors de l'envoi d'une demande à /customers/41224d776a326fb40f000001
et qu'un document avec _id
41224d776a326fb40f000001
n'existe pas, doc
est null
et je retourne 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);
});
};
Cependant, lorsque _id
ne correspond pas à ce que Mongoose attend comme "format" (je suppose), par exemple avec GET /customers/foo
, une erreur étrange est renvoyée:
CastError: La conversion vers ObjectId a échoué pour la valeur "foo" sur le chemin "_id".
Alors, quelle est cette erreur?
La méthode findById
de Mongoose convertit le paramètre id
dans le type du champ _id
du modèle afin qu'il puisse interroger correctement le document correspondant. Ceci est un ObjectId mais "foo"
n'est pas un ObjectId valide et la conversion échoue.
Cela n'arrive pas avec 41224d776a326fb40f000001
car cette chaîne est un ObjectId valide.
Une façon de résoudre ce problème consiste à ajouter une vérification avant votre appel findById
pour voir si id
est un ObjectId valide ou différent de celui-ci:
if (id.match(/^[0-9a-fA-F]{24}$/)) {
// Yes, it's a valid ObjectId, proceed with `findById` call.
}
Utilisez les fonctions existantes pour vérifier ObjectID.
var mongoose = require('mongoose');
mongoose.Types.ObjectId.isValid('your id here');
Est-ce que vous analysez cette chaîne en tant que ObjectId
?
Ici, dans mon application, ce que je fais est:
ObjectId.fromString( myObjectIdString );
Vous pouvez également utiliser ObjectId.isValid comme suit:
if (!ObjectId.isValid(userId)) return Error({ status: 422 })
J'ai le même problème que j'ajoute
_ id: String .in schema puis il commence à fonctionner
C'est une vieille question, mais vous pouvez également utiliser le paquet express-validator pour vérifier les paramètres de la demande.
validateur express version 4 (dernière):
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);
});
});
validateur express version 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);
});
});
});
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"});
}
le mieux est de vérifier la validité
J'ai dû déplacer mes itinéraires par-dessus d'autres itinéraires capturant les paramètres d'itinéraire:
// require express and express router
const express = require("express");
const router = express.Router();
// move this `/post/like` route on top
router.put("/post/like", requireSignin, like);
// keep the route with route parameter `/:postId` below regular routes
router.get("/post/:postId", singlePost);
La façon dont je résous ce problème est de transformer l'identifiant en une chaîne
je l'aime fantaisie avec backtick: `${id}`
cela devrait résoudre le problème sans surcharge
Je suis allé avec une adaptation de la solution @gustavohenke, en implémentant ObjectId cast dans un try-catch encapsulé autour du code d'origine pour tirer parti de l'échec de la conversion ObjectId comme méthode de validation.
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);
}
};
Utilisez toujours les conditions mongoose.Types.ObjectId('your id')
for dans votre requête pour valider le champ d'identifiant avant de l'exécuter. Ainsi, votre application ne plantera pas.
ObjectId est composé des éléments suivants.
La méthode correcte pour valider si objectId est valide consiste à utiliser la méthode statique de la classe ObjectId elle-même.
mongoose.Types.ObjectId.isValid (sample_object_id)
OU vous pouvez le faire
var ObjectId = require('mongoose').Types.ObjectId;
var objId = new ObjectId( (param.length < 12) ? "123456789012" : param );
comme mentionné ici La méthode de recherche de Mongoose avec $ ou condition ne fonctionne pas correctement
Détection et correction de l'erreur ObjectID
Je suis tombé sur ce problème en essayant de supprimer un article en utilisant de la mangouste et j'ai eu la même erreur. Après avoir examiné la chaîne de retour, j'ai trouvé qu'il y avait des espaces supplémentaires à l'intérieur de la chaîne renvoyée qui ont provoqué l'erreur pour moi. J'ai donc appliqué quelques-unes des réponses fournies ici pour détecter l'identifiant erroné, puis supprimer les espaces supplémentaires de la chaîne. Voici le code qui a fonctionné pour moi pour enfin résoudre le problème.
const mongoose = require("mongoose");
mongoose.set('useFindAndModify', false); //was set due to DeprecationWarning: Mongoose: `findOneAndUpdate()` and `findOneAndDelete()` without the `useFindAndModify`
app.post("/delete", function(req, res){
let checkedItem = req.body.deleteItem;
if (!mongoose.Types.ObjectId.isValid(checkedItem)) {
checkedItem = checkedItem.replace(/\s/g, '');
}
Item.findByIdAndRemove(checkedItem, function(err) {
if (!err) {
console.log("Successfully Deleted " + checkedItem);
res.redirect("/");
}
});
});
Cela a fonctionné pour moi et je suppose que si d'autres éléments commencent à apparaître dans la chaîne de retour, ils peuvent être supprimés de la même manière.
J'espère que ça aide.
//Use following to check if the id is a valid ObjectId?
var valid = mongoose.Types.ObjectId.isValid(req.params.id);
if(valid)
{
//process your code here
} else {
//the id is not a valid ObjectId
}
Chaîne de chaîne en ObjectId
import mongoose from "mongoose"; // ES6 or above
const mongoose = require('mongoose'); // ES5 or below
let userid = _id
console.log(mongoose.Types.ObjectId(userid)) //5c516fae4e6a1c1cfce18d77
Si quelqu'un se heurte à cela, ce qui a résolu le problème pour moi a été de passer d'une citation unique dans l'exigence à ".
Au lieu de:
const something = require('./models/something');
utilisation:
const something = require(`./models/something`);
Sachez que ça a l'air drôle, mais que ça fonctionne.