Je fais des recherches MongoDB en convertissant une chaîne en BSON. Est-il possible pour moi de déterminer si la chaîne que j'ai est un ObjectID valide pour Mongo avant d'effectuer la conversion?
Voici le coffeescript de ma fonction findByID actuelle. Cela fonctionne très bien, mais j'aimerais rechercher un attribut différent si je détermine que la chaîne n'est pas un identifiant.
db.collection "pages", (err, collection) ->
collection.findOne
_id: new BSON.ObjectID(id)
, (err, item) ->
if item
res.send item
else
res.send 404
J'ai trouvé que le validateur ObjectId Mongoose fonctionne pour valider des objectIds valides, mais j'ai trouvé quelques cas où des identifiants non valides étaient considérés comme valides. (par exemple: n'importe quelle chaîne de 12 caractères)
var ObjectId = require('mongoose').Types.ObjectId;
ObjectId.isValid('Microsoft123'); //true
ObjectId.isValid('timtomtamted'); //true
ObjectId.isValid('551137c2f9e1fac808a5f572'); //true
Ce qui a fonctionné pour moi est de convertir une chaîne en objectId, puis de vérifier que la chaîne d'origine correspond à la valeur de chaîne de objectId.
new ObjectId('timtamtomted'); //616273656e6365576f726b73
new ObjectId('537eed02ed345b2e039652d2') //537eed02ed345b2e039652d2
Cela fonctionne car les identifiants valides ne changent pas lorsqu'ils sont convertis en un ObjectId, mais une chaîne qui obtient une valeur false valide changera lorsqu'elle sera convertie en un objectId.
Vous pouvez utiliser une expression régulière pour tester cela:
CoffeeScript
if id.match /^[0-9a-fA-F]{24}$/
# it's an ObjectID
else
# nope
JavaScript
if (id.match(/^[0-9a-fA-F]{24}$/)) {
// it's an ObjectID
} else {
// nope
}
J'ai utilisé le pilote de noeud natif mongodb pour le faire dans le passé. La méthode isValid vérifie que la valeur est un ObjectId BSON valide. Voir la documentation ici.
var ObjectID = require('mongodb').ObjectID;
console.log( ObjectID.isValid(12345) );
Voici un code que j'ai écrit à partir de la réponse de @ andy-macleod.
Il peut prendre un int ou une chaîne ou ObjectId et renvoie un ObjectId valide si la valeur transmise est valide ou null si elle n'est pas valide:
var ObjectId= require('mongoose').Types.ObjectId;
function toObjectId(id) {
var stringId = id.toString().toLowerCase();
if (!ObjectId.isValid(stringId)) {
return null;
}
var result = new ObjectId(stringId);
if (result.toString() != stringId) {
return null;
}
return result;
}
mongoose.Types.ObjectId.isValid (chaîne) renvoie toujours True si la chaîne contient 12 lettres.
let firstUserID = '5b360fdea392d731829ded18';
let secondUserID = 'aaaaaaaaaaaa';
console.log(mongoose.Types.ObjectId.isValid(firstUserID)); // true
console.log(mongoose.Types.ObjectId.isValid(secondUserID)); // true
let checkForValidMongoDbID = new RegExp("^[0-9a-fA-F]{24}$");
console.log(checkForValidMongoDbID.test(firstUserID)); // true
console.log(checkForValidMongoDbID.test(secondUserID)); // false
Pour mongoose, utilisez la fonction isValid () pour vérifier si objectId est valide ou non.
Exemple :
var ObjectId = mongoose.Types.ObjectId;
if(ObjectId.isValid(req.params.documentId)){
console.log('Object id is valid');
}else{
console.log('Invalid Object id');
}
Il m'a fallu un certain temps pour trouver une solution valable, car celle proposée par @Andy Macleod, qui consistait à comparer la valeur objectId avec sa propre chaîne, bloquait le serveur Express.js sur:
var view_task_id_temp=new mongodb.ObjectID("invalid_id_string"); //this crashed
Je viens d'utiliser un simple essai d'essayer de résoudre ce problème.
var mongodb = require('mongodb');
var id_error=false;
try{
var x=new mongodb.ObjectID("57d9a8b310b45a383a74df93");
console.log("x="+JSON.stringify(x));
}catch(err){
console.log("error="+err);
id_error=true;
}
if(id_error==false){
// Do stuff here
}
Si vous avez la chaîne hexagonale, vous pouvez utiliser ceci:
ObjectId.isValid(ObjectId.createFromHexString(hexId));
Le seul moyen que j'ai trouvé est de créer un nouvel ObjectId avec la valeur que je veux vérifier. Si l'entrée est égale à la sortie, l'identifiant est valide:
function validate(id) {
var valid = false;
try
{
if(id == new mongoose.Types.ObjectId(""+id))
valid = true;
}
catch(e)
{
valid = false;
}
return valid;
}
> validate(null)
false
> validate(20)
false
> validate("abcdef")
false
> validate("5ad72b594c897c7c38b2bf71")
true
Le moyen le plus simple consiste à envelopper votre méthode ObjectId dans un service try and catch. Ensuite, vous utilisez ce service pour gérer les identifiants d'Objecet, au lieu d'utiliser directement la méthode:
var ObjectId = REQUIRE OR IMPORT ...
// service
function oid(str) {
try {
return ObjectId(str);
} catch(err) {
return false;
}
}
// usage
if (oid(USER_INPUT)) {
// continue
} else {
// throw error
}
Vous pouvez également envoyer des accessoires nuls ou vides pour obtenir un nouvel identifiant généré.