Wenn Sie eine Anfrage an /customers/41224d776a326fb40f000001
senden und ein Dokument mit _id
41224d776a326fb40f000001
nicht vorhanden ist, ist doc
null
und ich gebe einen 404
zurück:
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);
});
};
Wenn _id
jedoch nicht mit dem übereinstimmt, was Mongoose als "Format" erwartet (ich nehme an), zum Beispiel mit GET /customers/foo
, wird ein seltsamer Fehler zurückgegeben:
CastError: Die Umwandlung in ObjectId ist für den Wert "foo" im Pfad "_id" fehlgeschlagen.
Also, was ist dieser Fehler?
Die findById
-Methode von Mongoose wandelt den id
-Parameter in den Typ des _id
-Felds des Modells um, damit dieses das entsprechende Dokument richtig abfragen kann. Dies ist eine ObjectId, aber "foo"
ist keine gültige ObjectId, daher schlägt die Umwandlung fehl.
Dies passiert nicht bei 41224d776a326fb40f000001
, da diese Zeichenfolge eine gültige ObjectId ist.
Um dies zu beheben, können Sie vor dem Aufruf von findById
eine Prüfung hinzufügen, um zu prüfen, ob id
eine gültige ObjectId ist oder nicht:
if (id.match(/^[0-9a-fA-F]{24}$/)) {
// Yes, it's a valid ObjectId, proceed with `findById` call.
}
Verwenden Sie vorhandene Funktionen zur Überprüfung der ObjectID.
var mongoose = require('mongoose');
mongoose.Types.ObjectId.isValid('your id here');
Analysieren Sie diese Zeichenfolge als ObjectId
?
Hier in meiner Bewerbung mache ich:
ObjectId.fromString( myObjectIdString );
Sie können ObjectId.isValid auch wie folgt verwenden:
if (!ObjectId.isValid(userId)) return Error({ status: 422 })
Ich habe das gleiche Problem, das ich hinzufüge
_ id: String .in Schema, dann beginnt die Arbeit
Dies ist eine alte Frage, Sie können jedoch auch das Paket "Express-Validator" verwenden, um die Anfrageparameter zu überprüfen
express-Validator Version 4 (aktuell):
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:
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"});
}
am besten ist es, die Gültigkeit zu prüfen
Ich musste meine Routen über andere Routen verschieben, für die die Routenparameter gelten:
// 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);
Die Art und Weise, wie ich dieses Problem behebe, ist die Umwandlung der ID in eine Zeichenfolge
ich mag es ausgefallen mit Backtick: `${id}`
dies sollte das Problem ohne zusätzlichen Aufwand beheben
Ich ging zu einer Anpassung der @ gustavohenke-Lösung und implementierte cast ObjectId in einen try-catch um den ursprünglichen Code gewickelt , um den Ausfall des ObjectId-Castings als Validierungsmethode zu nutzen.
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);
}
};
Verwenden Sie immer mongoose.Types.ObjectId('your id')
für Bedingungen in Ihrer Abfrage, um das ID-Feld zu überprüfen, bevor Sie die Abfrage ausführen, da Ihre App nicht abstürzt.
ObjectId besteht aus folgenden Dingen.
Die korrekte Methode für die Validierung der objectId ist die Verwendung der statischen Methode aus der ObjectId-Klasse.
mongoose.Types.ObjectId.isValid (sample_object_id)
ODER Sie können das tun
var ObjectId = require('mongoose').Types.ObjectId;
var objId = new ObjectId( (param.length < 12) ? "123456789012" : param );
wie hier erwähnt Mongoose's find-Methode mit $ oder Bedingung funktioniert nicht richtig
Erkennen und Korrigieren des ObjectID-Fehlers
Ich bin auf dieses Problem gestoßen, als ich versuchte, einen Gegenstand mit Mungo zu löschen, und habe den gleichen Fehler erhalten. Nachdem ich mir die Rückgabe-Zeichenfolge angesehen hatte, stellte ich fest, dass die zurückgegebene Zeichenfolge einige zusätzliche Leerzeichen enthält, die den Fehler für mich verursacht haben. Daher habe ich einige der hier angegebenen Antworten angewendet, um die fehlerhafte ID zu ermitteln, und dann die zusätzlichen Leerzeichen aus der Zeichenfolge entfernt. Hier ist der Code, mit dem ich das Problem endgültig gelöst habe.
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("/");
}
});
});
Dies hat bei mir funktioniert und ich gehe davon aus, dass andere Elemente in ähnlicher Weise entfernt werden können, wenn sie in der Rückgabezeichenfolge angezeigt werden.
Ich hoffe das hilft.
//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
}
Zeichenkette in ObjectId umwandeln
import mongoose from "mongoose"; // ES6 or above
const mongoose = require('mongoose'); // ES5 or below
let userid = _id
console.log(mongoose.Types.ObjectId(userid)) //5c516fae4e6a1c1cfce18d77
Wenn jemand auf dieses Problem stößt, wurde es für mich dadurch gelöst, dass ich von einem einfachen Anführungszeichen in "erforderlich" zu "erforderlich" wechselte.
Anstatt:
const something = require('./models/something');
benutzen:
const something = require(`./models/something`);
Weiß, es klingt lustig, aber es funktioniert tatsächlich.