경로 "_id"에서 값 XXX에 대한 Mongoose 오류 ObjectId에 캐스트 실패했습니다.
" " " 에 을 /customers/41224d776a326fb40f000001
및 문서가 있습니다._id
41224d776a326fb40f000001
하지 않습니다.doc
null
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★」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);
});
};
<고객명>의 _id
는, 「이라고 하는 Mongoose 의 하지 않습니다(제 생각에 「포맷 예를 , 「Mongoose」의 「포맷」과 일치하지 않습니다.GET /customers/foo
하다
CastError: 경로 "_id"에서 값 "foo"에 대해 ObjectId로 캐스트하지 못했습니다.
그럼 이 오류는 뭐죠?
구 mong mongfindById
가 「」를 합니다.id
_id
일치하는 문서를 올바르게 쿼리할 수 있도록 합니다.이지만 ObjectId입니다."foo"
ObjectId를 선택합니다.
41224d776a326fb40f000001
ObjectId를 사용합니다.
하려면 , 「」의 앞에 .findById
를 하다id
.ObjectId는 ObjectId입니다.
if (id.match(/^[0-9a-fA-F]{24}$/)) {
// Yes, it's a valid ObjectId, proceed with `findById` call.
}
기존 함수를 사용하여 개체 확인아이디
var mongoose = require('mongoose');
mongoose.Types.ObjectId.isValid('your id here');
루트 파라미터를 캐치하고 있는 다른 루트 위에 루트를 이동해야 했습니다.
// 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);
것과 .
.에서 string을 실행한 후: .string을 시작합니다.
이와 같이 2개의 다른 루트가 있는 경우 루트가 일치하지 않을 수 있습니다.
router.route("/order/me") //should come before the route which has been passed with params
router.route("/order/:id")
파라미터를 사용하고 있는 루트를, 나에게 통상의 루트 뒤에 배치하는 것에 주의해 주세요.
은 ""로 ?ObjectId
이 어플리케이션에서 하는 일은 다음과 같습니다.
ObjectId.fromString( myObjectIdString );
mongoose에 ID를 때 합니다.하기 전에 mongoose를 하여 먼저 후 진행합니다.isValid
import mongoose from "mongoose";
// add this inside your route
if( !mongoose.Types.ObjectId.isValid(id) ) return false;
', '아까', '아까', '아까'를 붙여야 요._id: Object
모든 게 잘 풀렸어요
2019년 11월 19일 기준
하시면 됩니다.isValidObjectId(id)
5.7.12mongoose '5.7.12'
https://mongoosejs.com/docs/api/mongoose.html#mongoose_Mongoose-isValidObjectId
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"});
}
유효성을 확인하는 것이 최선이다.
다음과 같이 ObjectId.isValid를 사용할 수도 있습니다.
if (!ObjectId.isValid(userId)) return Error({ status: 422 })
위의 해결 방법이 효과가 없는 경우.POST 루트에 GET 요구를 송신하고 있는지 여부를 체크합니다.
그것은 나에게 그렇게 단순하고 어리석었다.
파라미터 이름 "id"를 "_id"로 변경하기만 하면 됩니다.
//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
}
저는 최근에 비슷한 일을 겪었고, Mongoose ObjectId 오류인지 확인하기 위해 오류를 잡아서 해결했습니다.
app.get("/:userId", (req, res, next) => {
try {
// query and other code here
} catch (err) {
if (err.kind === "ObjectId") {
return res.status(404).json({
errors: [
{
msg: "User not found",
status: "404",
},
],
});
}
next(err);
}
});
모든 ID를 쿼리에 사용하기 전에 검증할 수도 있습니다(이것이 최선의 방법이라고 생각합니다).
// Assuming you are using Express, this can return 404 automatically.
app.post('/resource/:id([0-9a-f]{24})', function(req, res){
const id = req.params.id;
// ...
});
...또는 Mongoose에 패치를 적용하여 이러한 캐스팅 오류를 무시하고 대신 문자열 표현을 사용하여 쿼리를 수행할 수 있습니다.당신의 질문은 물론 아무것도 찾지 못하겠지만, 어쨌든 당신은 그렇게 되길 원할 것입니다.
import { SchemaType } from 'mongoose';
let patched = false;
export const queryObjectIdCastErrorHandler = {
install,
};
/**
* Monkey patches `mongoose.SchemaType.prototype.castForQueryWrapper` to catch
* ObjectId cast errors and return string instead so that the query can continue
* the execution. Since failed casts will now use a string instead of ObjectId
* your queries will not find what they are looking for and may actually find
* something else if you happen to have a document with this id using string
* representation. I think this is more or less how MySQL would behave if you
* queried a document by id and sent a string instead of a number for example.
*/
function install() {
if (patched) {
return;
}
patch();
patched = true;
}
function patch() {
// @ts-ignore using private api.
const original = SchemaType.prototype.castForQueryWrapper;
// @ts-ignore using private api.
SchemaType.prototype.castForQueryWrapper = function () {
try {
return original.apply(this, arguments);
} catch (e) {
if ((e.message as string).startsWith('Cast to ObjectId failed')) {
return arguments[0].val;
}
throw e;
}
};
}
저는 @gustavoenke 솔루션을 채택하여 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);
}
};
오래된 질문이지만 express-validator 패키지를 사용하여 요청 매개 변수를 확인할 수도 있습니다.
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 버전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);
});
});
});
「」를 사용합니다.mongoose.Types.ObjectId('your id')
쿼리의 조건에 대해서는 쿼리를 실행하기 전에 id 필드의 유효성을 확인합니다.그 결과 앱이 크래쉬하지 않습니다.
이로 인해 문제가 이 문제를 했습니다.mongoose.ObjectId(id)
없이Types
ObjectId는 다음과 같은 요소로 구성됩니다.
- Unix Epoch 이후의 초수를 나타내는 4바이트 값
- 5바이트 랜덤 값(머신 ID 3바이트 및 프로세서 ID 2바이트)
- 랜덤 값으로 시작하는 3바이트 카운터
objectId가 유효한지 여부를 확인하는 올바른 방법은 ObjectId 클래스 자체의 정적 메서드를 사용하는 것입니다.
mongoose.Types.ObjectId.isValid(sample_object_id)
제 경우 비슷한 루트가 이 문제를 일으켰습니다.
Router.get("/:id", getUserById);
Router.get("/myBookings",getMyBookings);
위의 코드에서는 "/myBookings"를 라우팅하기 위한 get 요구가 있을 때마다 req.params.id이 유효한 ObjectId가 아닌 "myBookings"와 동일한 첫 번째 루트로 이동합니다.
양쪽 루트의 경로를 다르게 함으로써 수정할 수 있습니다.
뭐 이런 거
Router.get("/user/:id", getUserById);
Router.get("/myBookings",getMyBookings);
id 루트 후에 호출한 다음 루트를 id 루트에 연결할 수 없었기 때문에 castError가 발생하고 있습니다.id 루트를 마지막 루트로 선언해야 합니다.
이 문제를 해결하는 방법은 ID를 문자열로 변환하는 것입니다.
에 들어요.`${id}`
오버헤드 없이 문제를 해결할 수 있습니다.
2022년 10월 갱신
를 사용하는 것이 가장 좋습니다.
{id: id} // if you have an id property defined
또는
{_id: new ObjectId(id)} // and search for the default mongodb _id
아니면 이렇게 할 수도 있고
var ObjectId = require('mongoose').Types.ObjectId; var objId = new ObjectId( (param.length < 12) ? "123456789012" : param );
여기에 언급된 바와 같이 $or 조건을 가진 Mongoose의 find 메서드가 제대로 작동하지 않습니다.
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
오류 검출 및 아이디 ★★
를 사용하여 할 때 이했는데, 했습니다.mongoose는 mongoose로 되어 있습니다.리턴 스트링을 살펴본 결과 리턴 스트링 안에 여분의 공간이 있어 오류가 발생하였습니다.그래서 여기 제시된 몇 가지 답변을 적용하여 잘못된 ID를 감지하고 문자열에서 여백을 제거했습니다.이 문제를 최종적으로 해결할 수 있었던 코드는 다음과 같습니다.
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("/");
}
});
});
이것은 나에게 효과가 있었고, 다른 아이템이 반환 문자열에 표시되기 시작하면 같은 방법으로 아이템을 삭제할 수 있을 것입니다.
이게 도움이 됐으면 좋겠어요.
저도 같은 실수를 했지만 질문과는 다른 상황이지만 누군가에게 도움이 될지도 모릅니다.
문제는 버클을 추가하는 것이었습니다.
틀렸다:
const gamesArray = [myId];
const player = await Player.findByIdAndUpdate(req.player._id, {
gamesId: [gamesArray]
}, { new: true }
정답:
const gamesArray = [myId];
const player = await Player.findByIdAndUpdate(req.player._id, {
gamesId: gamesArray
}, { new: true }
저의 경우 파라미터 id 길이가 25였기 때문에 파라미터 id의 첫 글자를 트리밍하여 시도하였습니다.됐다.
블록 따옴표
const paramId = req.params.id;
if(paramId.length === 25){
const _id = paramId.substring(1, 25);
}
문자열 개체를 ObjectId 인스턴스로 변경하는 메서드는 더 이상 존재하지 않습니다.새로운 메서드 createFromHexString()이 추가되었습니다.
const _id = mongoose.Types.ObjectId.fromString(id); // old method not available
const _id = mongoose.Types.ObjectId.createFromHexString(id); // new method.
id 로서 24 문자 미만의 문자열을 송신하는 경우 발생할 수 있습니다.
언급URL : https://stackoverflow.com/questions/14940660/whats-mongoose-error-cast-to-objectid-failed-for-value-xxx-at-path-id
'sourcetip' 카테고리의 다른 글
$190 get 파라미터가 동작하지 않는다 (0) | 2023.02.27 |
---|---|
GSON - String에서 JSON 값을 가져옵니다. (0) | 2023.02.18 |
Webrick은 반응이 매우 느리다.어떻게 하면 빨라요? (0) | 2023.02.17 |
PowerShell을 사용하여 JSON 파일을 업데이트하는 방법 (0) | 2023.02.17 |
리액트 리덕스: 리덕터에 논리가 포함되어 있는지 여부 (0) | 2023.02.17 |