CastError猫鼬

时间:2017-03-31 06:01:32

标签: node.js mongodb express mongoose

我在express / nodejs项目中使用mongodb。我有一个嵌套模式,主题有类别

鉴于此架构:

var ControlCategorySchema = new Schema({
    name: {
        type: String,
        Required: 'Please enter the category name'
    }
});
ControlCategorySchema.plugin(autoIncrement.plugin, 'ControlCategorySchemaCounter');

var ThemeSchema = new Schema({
    name : String,
    category : {type: Schema.Types.ObjectId, ref: 'ControlCategorySchema'}
});
ThemeSchema.plugin(autoIncrement.plugin, 'ThemeCounter');

以下控制器代码:

exports.create_a_theme = function(req, res) {
    console.log(req.body.category);
    if (req.body.category != undefined) {
        addTheme(req,res,req.body.category);
    }

};

function addTheme(req,res,category_id) {
    console.log("category id " + category_id);
    ControlCategory.findById(category_id, function (err, category_found) {
        if (err)
            res.send(err)

        req.body.category = category_found;
        console.log("body is " + req.body.category);
        var new_theme = new Theme();
        new_theme.name = req.body.name;
        new_theme.category = req.body.category;
        new_theme.save(function (err, theme) {
            if (err)
                res.send(err);
            console.log(theme);
            res.json(theme);
        });
    });
}

任何人都可以帮助解决发布此json的原因

{ 
    "name": "Application Security",
    "category": 0
}

导致以下错误:

{
  "errors": {
    "category": {
      "message": "Cast to ObjectID failed for value \"{ _id: 0, name: 'Application Security', __v: 0 }\" at path \"category\"",
      "name": "CastError",
      "stringValue": "\"{ _id: 0, name: 'Application Security', __v: 0 }\"",
      "kind": "ObjectID",
      "value": {
        "_id": 0,
        "name": "Application Security",
        "__v": 0
      },
      "path": "category",
      "reason": {
        "message": "Cast to ObjectId failed for value \"{ _id: 0, name: 'Application Security', __v: 0 }\" at path \"category\"",
        "name": "CastError",
        "stringValue": "\"{ _id: 0, name: 'Application Security', __v: 0 }\"",
        "kind": "ObjectId",
        "value": {
          "_id": 0,
          "name": "Application Security",
          "__v": 0
        },
        "path": "category"
      }
    }
  },
  "message": "Theme validation failed",
  "name": "ValidationError"
}

有一点非常奇怪的是,我在另一个模式和控制器代码上做了几乎相同的事情并且它有效!

var AssessmentSchema = new Schema({
    name: {
        type: String,
        Required: 'Kindly enter the name of the assessment'
    },
    Created_date: {
        type: Date,
        default: Date.now
    },
    status: { type: Schema.ObjectId, ref: 'AssessmentStatus' },
});

var AssessmentStatusSchema = new Schema({
    name: {
        type: String,
        Required: 'Please enter the name of the assessment status'
    }

});

exports.create_an_assessment = function(req, res) {
    console.log(req.body.status);
    if (req.body.status == undefined) {
        AssessmentStatus.findOne({"name": "Due For Assessment"}, function (err, assessment_status) {
            if (err)
                res.send(err)
            addAssessment(req,res,assessment_status._id);
        });
    }
    else {

        addAssessment(req,res,req.body.status);
    }

};

function addAssessment(req,res,status_id) {
    console.log("status id " + status_id);
    AssessmentStatus.findById(status_id, function (err, assessment_status) {
        if (err)
            res.send(err)
        req.body.status = assessment_status;
        console.log("body is " + req.body.status);
        var new_assessment = new Assessment();
        new_assessment.name = req.body.name;
        new_assessment.status = assessment_status;
        new_assessment.save(function (err, assessment) {
            if (err)
                res.send(err);
            console.log(assessment);
            res.json(assessment);
        });
    });
}

然后我发布了相同类型的数据

{
    "name": "Assessment 10",
    "status": 6
}

并获得所需的结果

{
  "__v": 0,
  "_id": 28,
  "status": {
    "_id": 6,
    "name": "Due For Assessment",
    "__v": 0
  },
  "name": "Assessment 10",
  "Created_date": "2017-03-31T06:48:21.999Z"
}

我不知道有什么不同?

3 个答案:

答案 0 :(得分:1)

当您提供无效的ObjectId

时会发生此错误

mongo _id是12字节的BSON类型ObjectId

这里我添加了if-else来验证category_id是否是有效的ObjectId,如果它然后执行操作,否则抛出自定义错误消息

使用mongoose-autoincrement-package时 它使用Number类型而不是ObjectId和 ref属性类型将是Number而不是ObjectId,因此当您声明引用时,如果引用的模型,请记住将引用属性的类型更改为Number而不是ObjectId也在使用插件。

var ThemeSchema = new Schema({
    name : String,
    category : {type: Number, ref: 'ControlCategorySchema'}
});
function addTheme(req, res, category_id) {
    console.log("category id " + category_id);
    var cond = mongoose.Types.ObjectId.isValid(category_id)

    if (cond) {
        ControlCategory.findById(category_id, function (err, category_found) {
            if (err)
                res.send(err)

            req.body.category = category_found;
            console.log("body is " + req.body.category);
            var new_theme = new Theme();
            new_theme.name = req.body.name;
            new_theme.category = req.body.category._id;
            new_theme.save(function (err, theme) {
                if (err)
                    res.send(err);
                console.log(theme);
                res.json(theme);
            });
        });
    } else {
        res.json({ message: 'not a valid object id' });
    }
}

答案 1 :(得分:0)

ThemeSchema.category的类型为Schema.Types.ObjectId,而'0'不是有效的mongo ID。有效的mongo id是12字节十六进制,例如507f1f77bcf86cd799439011

此处有两个选项,可以将ThemeSchema.category定义为number,也可以指定有效的mongo ID。由于您在ControlCategorySchema中引用了ThemeSchema,我想以后这是唯一的选择。

答案 2 :(得分:0)

看起来https://stackoverflow.com/users/5127888/p0k8给出了合适的答案,谢谢!

而不是类别:{type:Schema.Types.ObjectId,ref:'ControlCategorySchema'} do category:{type:Number,ref:'ControlCategorySchema'}

那很有用。虽然仍然困扰我为什么评估一个成功