ObjectIdFromHex在相同字符串上出现无效字节错误

huangapple go评论85阅读模式
英文:

ObjectIdFromHex invalid byte error on identical strings

问题

我正在尝试在我的 Golang REST API 中实现一个 FindOne 方法。问题出在当我需要通过 ID 进行搜索时。我必须将 ID 转换为数据库可读的格式,所以我使用了 primitive.ObjectIDFromHex(id) 方法。
问题是,当我使用来自 URL GET 参数的 id 调用该方法时,它会抛出一个错误:

2021/06/19 06:56:15 encoding/hex: invalid byte: U+000A

只有当我使用硬编码的 ID 调用它时,不会出现这个编码错误。请参考下面的代码。

func Admin(id string) (bson.M, error) {
    coll, err := db.ConnectToCollection("admin")
    if err != nil {
        log.Fatal(err)
    }
    var admin bson.M

    HardCoded := "60cb275c074ab46a1aeda45e"

    fmt.Println(HardCoded) // 为了确保:这两个字符串看起来是相同的
    fmt.Println(id) 

    objetId, err := primitive.ObjectIDFromHex(id) // 抛出编码错误
    // objetId, err := primitive.ObjectIDFromHex(HardCoded) // 不会抛出编码错误

    if err != nil {
        log.Fatal(err)
    }
    var ctx = context.TODO()

    if err := coll.FindOne(ctx, bson.M{"_id": objetId}).Decode(&admin); err != nil {
        log.Fatal(err)
    }
    return admin, nil
}

当然,你可能想知道参数 id 是从哪里来的。
这是代码:

func GetAdmin(w http.ResponseWriter, r *http.Request) {
    w.Header().Set("Content-Type", "application/json")
    params := mux.Vars(r)
    admin, err := Admin(params["id"]) // 调用上面的 Admin 函数

    if err != nil {
        fmt.Println(err)
        http.Error(w, err.Error(), http.StatusUnauthorized)
    } else {
        JSON, err := json.Marshal(admin)
        if err != nil {
            http.Error(w, err.Error(), http.StatusInternalServerError)
        }
        w.Write(JSON)
    }
}
英文:

I'm trying to implement a FindOne method in my Golang REST API. The trouble comes where i have to search by ID. I have to convert the ID into something readable by the database, so i use primitive.ObjectIDFromHex(id)
The problem is that this method throws an error :

2021/06/19 06:56:15 encoding/hex: invalid byte: U+000A

ONLY when i call it with the id that comes from my URL GET params.
I did two versions : one with hard-coded ID, and one with GET ID. See code below.

func Admin(id string) (bson.M, error) {
	coll, err := db.ConnectToCollection("admin")
	if err != nil {
		log.Fatal(err)
	}
	var admin bson.M

	HardCoded := "60cb275c074ab46a1aeda45e"

	fmt.Println(HardCoded) // Just to be sure : the two strings seem identical
	fmt.Println(id) 

	objetId, err := primitive.ObjectIDFromHex(id) // throws encoding error
	// objetId, err := primitive.ObjectIDFromHex(HardCoded) // Doesnt throw encoding err

	if err != nil {
		log.Fatal(err)
	}
	var ctx = context.TODO()

	if err := coll.FindOne(ctx, bson.M{"_id": objetId}).Decode(&admin); err != nil {
		log.Fatal(err)
	}
	return admin, nil
}

Of course, you'll want to know where the param id comes from.
Here you go :

func GetAdmin(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "application/json")
	params := mux.Vars(r)
	admin, err := Admin(params["id"]) // Calling the Admin function above

	if err != nil {
		fmt.Println(err)
		http.Error(w, err.Error(), http.StatusUnauthorized)
	} else {
		JSON, err := json.Marshal(admin)
		if err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
		}
		w.Write(JSON)
	}
}

答案1

得分: 3

修剪 id 结尾的换行符:

id = strings.TrimSpace(id)

在调试此类问题时,使用 %q 格式化动词。换行符在此输出中清晰可见:

fmt.Printf("%q\n", HardCoded) // 输出 "60cb275c074ab46a1aeda45e"
fmt.Printf("%q\n", id) // 输出 "60cb275c074ab46a1aeda45e\n"

英文:

Trim the line feed from the end of id:

id = strings.TrimSpace(id)

Use the %q format verb when debugging issues like this. The line feed is clearly visible in this output:

fmt.Printf("%q\n", HardCoded) // prints "60cb275c074ab46a1aeda45e"
fmt.Printf("%q\n", id)        // prints "60cb275c074ab46a1aeda45e\n"

huangapple
  • 本文由 发表于 2021年6月19日 13:17:19
  • 转载请务必保留本文链接:https://go.coder-hub.com/68043857.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定