【问题标题】:CastError: Cast to ObjectId failed for value "test33" (type string) at path "_id" for modelCastError:模型的路径 \"_id\" 中的值 \"test33\"(类型字符串)转换为 ObjectId 失败
【发布时间】:2022-09-29 22:28:18
【问题描述】:

我正在通过 Colt Steele 的 udemy 课程自学 Web 开发,但我碰壁了。我不知道为什么它在下面的代码中显示转换为 ObjectId 错误。我正在尝试调试它但找不到此错误消息的原因。我发现的唯一一件事是,当我通过将图像 url 输入/更新为没有 \"http://\" 的纯文本来创建/编辑数据时,它会显示此错误消息。请帮帮我..我在这里被困了几天,仍然不明白..

错误信息

const castError = new CastError();
                    ^

CastError: Cast to ObjectId failed for value \"test33\" (type string) at path \"_id\" for model \"Yelpcamp\"
    at model.Query.exec (/Users/doriyomi/Web Development/YELPCAMP/node_modules/mongoose/lib/query.js:4498:21)
    at model.Query.Query.then (/Users/doriyomi/Web Development/YELPCAMP/node_modules/mongoose/lib/query.js:4592:15)
    at processTicksAndRejections (node:internal/process/task_queues:96:5) {
  messageFormat: undefined,
  stringValue: \"test33\"\',
  kind: \'ObjectId\',
  value: \'test33\',
  path: \'_id\',
  reason: Error: Argument passed in must be a single String of 12 bytes or a string of 24 hex characters

应用程序.js

const express = require(\'express\');
const app = express();
const path = require(\'path\');
const mongoose = require(\'mongoose\');
const CampGround = require(\'./models/main\');
const methodOverride = require(\'method-override\'); 
const engine = require(\'ejs-mate\');

const db = mongoose.connect(\'mongodb://localhost:27017/yelpcamp\', {
    useNewUrlParser: true,
    useUnifiedTopology: true
});
db.then(()=> {
    console.log(\'connected to Mongo DB!\');
})


//to use req.body. it must be needed.
app.use(express.urlencoded({ extended: true }));
app.use(methodOverride(\'_method\'));

app.engine(\'ejs\', engine); //connect ejs-mate to ejs, then boilerplate layout can be used.
app.set(\'view engine\', \'ejs\');
app.set(\'views\', path.join(__dirname,\'views\'));

app.get(\'/main\', async (req, res)=> {
    console.log(\"Basic route opened!!\");
    const allData = await CampGround.find({});
    res.render(\'campground/main\', {allData});
})
app.post(\'/main\', async (req, res) => {
    console.log(\'New -> save() function opened\');
    console.log(`title: ${req.body.campground.title}`);
    console.log(`image: ${req.body.campground.image}`);
    console.log(`location: ${req.body.campground.location}`);
    console.log(`price: ${req.body.campground.price}`);

 
    const newData = new CampGround(req.body.campground);
    await newData.save();

    res.redirect(\'/main\');
})

app.get(\'/main/new\', (req, res) => {
    // console.log(\'new page works in express\');
    res.render(\'campground/new\');
})


app.get(\'/main/:id\', async (req, res) => {
    // console.log(\'id page works\');
    const {id} = req.params;
    const foundData = await CampGround.findById(id);
    res.render(\'campground/showbyid\',{foundData});
})

app.put(\'/main/:id\', async(req, res) => {
    // const {title, location} = req.body;
    // console.log(req.body.campground);
    await CampGround.findByIdAndUpdate(req.params.id,{...req.body.campground}, {new: true, useFindAndModify: false});
    
    res.redirect(`/main/${req.params.id}`);
})


app.get(\'/main/:id/edit\', async(req, res) => {
    const {id} = req.params;
    const foundData = await CampGround.findById(id);
    console.log(foundData);
    res.render(\'campground/edit\', {foundData});
})

app.delete(\'/main/:id\', async(req, res) => {
    await CampGround.findByIdAndDelete(req.params.id, {useFindAndModify: false});
    res.redirect(\'/main\');
})

app.listen(3000, ()=> {
    console.log(\"Port open!!\");
})

main.ejs //显示所有列表

<% layout(\'./layout/boilerplate\') %>

<div class=\"container mt-5 mb-5\">
    <h1>Campgrounds!!</h1>
    <% for(let a of allData.reverse()) { %>
        <div class=\"card w-75\">
            <div class=\"row\">
                <div class=\"col-md-5\">
                    <img src=\"<%=a.image%>\" class=\"img-fluid img-thumbnail\">
                </div>

                <div class=\"col-md-7\">
                    <div class=\"card-body\">
                        <h5 class=\"card-title\">
                            <%=a.title%>
                        </h5>
                        <h6 class=\"card-subtitle mb-2 text-muted\">
                            <%=a.location%>
                        </h6>
                        <p class=\"card-text\">
                            <%=a.description%><br><br>
                                <a href=\"/main/<%=a._id%>\" class=\"btn btn-primary\">Detail</a>
                        </p>
                    </div>
                </div>
            </div>
        </div>
    <% } %>
</div>

new.ejs // 列表创建部分

<% layout(\'./layout/boilerplate\') %>
<div class=\"row mt-5\">
    <h1 class=\"text-center\">New Data Creation</h1>
    <div class=\"col-md-6 offset-3\">
        <form action=\"/main\" method=\"POST\">
            <div class=\"mb-3\">
                <label class=\"form-label\" for=\"titleid\">Title: </label>
                <input class=\"form-control\" type=\"text\" id=\"titleid\" name=\"campground[title]\" placeholder=\"Title here\">
            </div>

            <div class=\"mb-3\">
                <label class=\"form-label\" for=\"locationid\">Location: </label>
                <input class=\"form-control\" type=\"text\" id=\"locationid\" name=\"campground[location]\" placeholder=\"Location here\">
            </div>
            
            <label class=\"form-label\" for=\"imgurlid\">URL </label>
            <div class=\"input-group mb-3\">
                <span class=\"input-group-text\">@</span>
                <input type=\"text\" class=\"form-control\" placeholder=\"IMG URL here\" id=imgurlid name=\"campground[image]\">
            </div>

            <label class=\"form-label\" for=\"priceid\">Price </label>
            <div class=\"input-group mb-3\">
                <span class=\"input-group-text\">$</span>
                <input type=\"text\" class=\"form-control\" placeholder=\"Price here\" id=priceid name=\"campground[price]\">
            </div>
            
            <div class=\"mb-3\">
                <label class=\"form-label\" for=\"descid\">Description: </label>
                <textarea class=\"form-control\" type=\"text\" id=\"descid\" name=\"campground[description]\" placeholder=\"Description here\"></textarea>
            </div>

            <div class=\"mb-3\">
                <button class=\"btn btn-success\" >create</button>
            </div>

            <a href=\"/main/\">Back to main</a>
        </form>
    </div>
</div>

  • mongoose 中期望 id 的 _id 属性应该是 24 个十六进制字符/12 个字节长,而在你的情况下不是。它的 \"test33\" 不是 12 个字节或 24 个十六进制字符,所以你需要更新它,这就是它无法投射的原因。改变你会很好
  • 感谢您的评论。我将 \"test33\" 更新为 6209ebcc31afb2535a673b08 之类的内容,现在它不显示错误消息,但我不明白为什么将这些数据保存在 _id 属性中,因为数据 \"test33\" 用于img url,不适用于 _id。我想我完全误解了一些东西:(
  • 我猜在某个地方你可能将“test33”称为_id或者可能是芒果中的图像url类型可能是ObjectId类型,所以基本上只需检查芒果中的图像url是否应该保存为文本,并且imageurl不应该指向_id你的代码
  • 我也这么认为。但我不知道我在哪里将“test33”称为_id。我浏览了整个代码但找不到它..你能帮我找到它吗?

标签: javascript mongodb mongoose ejs


【解决方案1】:

我有这个错误,我通过修改以下几行来解决它。 举个例子

app.get('/main/:id', async (req, res) => {
    // console.log('id page works');
    const {id} = req.params;
    const foundData = await CampGround.findById(id);
    res.render('campground/showbyid',{foundData});
})

in my code it would be:

app.get('/main/:id', async (req, res) => {
    // console.log('id page works');
    const id = req.params.id;
    const foundData = await CampGround.findOne({_id: id});
    res.render('campground/showbyid',{foundData});
})

我希望对您有所帮助,至少可以让您尝试另一种选择。

【讨论】:

    猜你喜欢
    • 2021-09-06
    • 1970-01-01
    • 1970-01-01
    • 2021-12-04
    • 1970-01-01
    • 2023-02-16
    • 2020-11-19
    • 2021-07-04
    • 2017-08-18
    相关资源
    最近更新 更多