Gin框架报错:无法将entities.Kendaraan作为*gin.Context使用
解决Go Gin类型不匹配错误:Cannot use 'kendaraan' (type entities.Kendaraan) as the type *gin.Context
问题根源
你遇到的类型不匹配问题,核心是函数设计用途不匹配:
process.go中的CreateKendaraan是Gin框架的HTTP请求处理器方法,专门接收*gin.Context参数,用于处理JSON格式的API请求(通过c.ShouldBindJSON解析请求体)。- 但你在
parsehtml.go中把它当成普通业务函数,直接传入entities.Kendaraan实例,自然触发类型错误。
另外,你的parsehtml.go代码里还有逻辑错误:kendaraan.NomorKendaraan被连续赋值两次,覆盖了之前的vecType值,应该把其中一个赋值给JenisID(对应数据库表的id_jenis字段)。
解决方案一:重构业务逻辑(推荐)
把数据库操作从HTTP处理器中抽离成独立业务函数,让表单处理和API请求复用同一份逻辑:
1. 修改process.go,新增独立插入函数
// InsertKendaraan 独立处理Kendaraan数据插入的业务函数 func (h *KendaraanHandler) InsertKendaraan(kendaraan entities.Kendaraan) (int, error) { kendaraan.TanggalServis = time.Now() stmt := `INSERT INTO data_servis_kendaraan ( id_jenis, nama_pemilik, nama_kendaraan, nomor_kendaraan, detail_servis, tanggal_servis, status_servis ) VALUES ($1, $2, $3, $4, $5, $6, $7) RETURNING id` var id int err := h.DB.QueryRow(stmt, kendaraan.JenisID, kendaraan.NamaPemilik, kendaraan.NamaKendaraan, int32(kendaraan.NomorKendaraan), kendaraan.DetailServis, kendaraan.TanggalServis, kendaraan.StatusServis).Scan(&id) return id, err } // 保留原有的Gin Handler,继续处理JSON请求 func (h *KendaraanHandler) CreateKendaraan(c *gin.Context) { var kendaraan entities.Kendaraan err := c.ShouldBindJSON(&kendaraan) if err != nil { fmt.Println("Received JSON payload:", c.Request.Body) c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } id, err := h.InsertKendaraan(kendaraan) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } response := gin.H{ "message": "Data telah dibuat!", "id": id, } c.JSON(http.StatusCreated, response) }
2. 修改parsehtml.go的调用逻辑
修正字段赋值错误,并调用新的业务函数:
} else if r.Method == http.MethodPost { r.ParseForm() var kendaraan entities.Kendaraan kendaraan.NamaPemilik = r.Form.Get("owner_name") kendaraan.NamaKendaraan = r.Form.Get("vec_name") // 修正字段赋值错误:vec_type对应id_jenis,vec_code对应nomor_kendaraan vecTypeStr := r.Form.Get("vec_type") vecType, err := strconv.ParseInt(vecTypeStr, 10, 32) if err != nil { panic(err) } kendaraan.JenisID = int32(vecType) vecCodeStr := r.Form.Get("vec_code") vecCode, err := strconv.ParseInt(vecCodeStr, 10, 32) if err != nil { panic(err) } kendaraan.NomorKendaraan = int32(vecCode) kendaraan.DetailServis = r.Form.Get("vec_detail") var data = make(map[string]interface{}) vErrors := validateData.Struct(kendaraan) if vErrors != nil { data["tabel"] = kendaraan data["validation"] = vErrors } else { // 调用新的业务函数插入数据 id, err := processModel.InsertKendaraan(kendaraan) if err != nil { data["error"] = fmt.Sprintf("Gagal menyimpan data: %v", err) } else { data["pesan"] = fmt.Sprintf("Data pasien berhasil disimpan (ID: %d)", id) } } temp, _ := template.ParseFiles("web/forms.html") temp.Execute(w, data) }
解决方案二:适配现有Handler(临时应急)
如果不想重构代码,可以通过Gin的响应捕获机制,把表单处理适配到现有Handler(耦合度较高,不推荐长期使用):
修改parsehtml.go的POST处理部分:
} else if r.Method == http.MethodPost { var kendaraan entities.Kendaraan // 用Gin的ShouldBind绑定表单数据(需确保结构体字段和表单name对应,或添加`form`标签) err := c.ShouldBind(&kendaraan) if err != nil { panic(err) } var data = make(map[string]interface{}) vErrors := validateData.Struct(kendaraan) if vErrors != nil { data["tabel"] = kendaraan data["validation"] = vErrors } else { // 捕获Handler的JSON响应 originalWriter := c.Writer rec := httptest.NewRecorder() c.Writer = rec // 调用原Handler processModel.CreateKendaraan(c) // 恢复原Writer c.Writer = originalWriter // 解析响应结果 if rec.Code == http.StatusCreated { data["pesan"] = "Data pasien berhasil disimpan" } else { var respErr map[string]string json.Unmarshal(rec.Body.Bytes(), &respErr) data["error"] = respErr["error"] } } temp, _ := template.ParseFiles("web/forms.html") temp.Execute(w, data) }
内容的提问来源于stack exchange,提问作者MiPremix
相关产品推荐
相关产品推荐

