Session Golang gorilla会话在重定向后保留表单数据

Session Golang gorilla会话在重定向后保留表单数据,session,go,gorilla,Session,Go,Gorilla,从逻辑的角度来看,我试图在重定向之间保留部分表单数据,以获得更好的用户体验,这样用户就不必再次填写整个表单,只需填写无效的部分 从编程的角度来看,我试图在gorilla会话的Flash中保存request.PostForm数据结构。重定向后,我唯一能够检索到的是内存地址的字符串表示形式,如[0xc2001c8b10] 下面是我在验证错误后保存flash数据的部分(在此之前执行了request.ParseForm()): 我还尝试向gob注册结构,但没有效果: func init() {

从逻辑的角度来看,我试图在重定向之间保留部分表单数据,以获得更好的用户体验,这样用户就不必再次填写整个表单,只需填写无效的部分

从编程的角度来看,我试图在gorilla会话的Flash中保存request.PostForm数据结构。重定向后,我唯一能够检索到的是内存地址的字符串表示形式,如[0xc2001c8b10]

下面是我在验证错误后保存flash数据的部分(在此之前执行了request.ParseForm()):

我还尝试向gob注册结构,但没有效果:

func init() {
    gob.Register(&url.Values{})
}
表单值以小写形式显示,例如“first_name”、“last_name”,如果这可能会对该行为产生任何影响的话

请记住,我成功地在重定向后检索到“消息”,唯一的问题是结构数据


我是否做错了什么,或者在重定向后是否存在另一种我不知道的填充部分表单的方法?

您的问题是您使用的是
接口{}
类型的值,这是泛型 当可以有多个类型时使用。gorilla的
会话.flash()就是这样的
方法,因为它可以返回任意用户数据(无论您输入什么)

您可以重现使用此代码()所经历的情况:

运行此程序时,您将看到如下输出:

某些数据:[0xc010000000]

这和你正在经历的一样。原因是
fmt.Println
没有 不逐步完成指针和接口的所有抽象级别,并在 某个级别,除非你让它打印所有内容。所以如果你使用

fmt.Printf("Some data: %#v\n", Flashes())
您确实会看到您的数据:

一些数据:[]接口{}{(*main.MyData)(0xc010000000)}

要访问数据,您必须做的是匹配类型的结果数据 你在期待。您必须执行()操作:

在上面的示例中,使用由
flash()
返回的第一个flash并断言为 类型为
*MyData
。如果它确实是这种类型,那么它的值将打印到控制台。 否则,将向控制台打印一条错误消息(尽管不是一条好消息)。 断言某个类型的变量后,断言的值为断言的值
类型。也就是说,上面示例中的
v
类型为
*MyType

,我建议使用gorilla/schema将表单数据解组到一个结构中,然后将该结构保存到会话中(确保按照gorilla/session文档进行gob.注册)。然后可以将结构传递回模板并重新填充表单。这是否意味着我必须使用预先指定的所有表单字段创建一个新的结构,以及将request.PostForm中的值转换为这个新结构的新func?您可以加入到
AddFlash
中,无论您想要什么,它都会返回您输入的任何内容的片段。你只需要确保你把它转换回你最后放进去的东西。没什么可做的了。示例中收到数字的原因是您使用了指针,
Println
不会解析指针。
type MyData struct {
    X int
}

// Simulate Flashes() from gorilla, which returns a slice of interface{} values.
func Flashes() []interface{} {
    x := &MyData{2}

    // Convert x to type interface{}
    interfaceValue := interface{}(x)

    // Put converted x into a slice of type []interface{}
    return []interface{}{interfaceValue}
}

func main() {
    // See that [0xSOMETHING] is printed
    fmt.Println("Some data:", Flashes())
}
fmt.Printf("Some data: %#v\n", Flashes())
func main() {
    value := Flashes()[0]

    v, ok := value.(*MyData)

    if ok {
        fmt.Println("Some data:", v)
    } else {
        fmt.Println("Oh no, there's something else stored than expected")
    }
}