Beego会话不会自动将数据传递给模板

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

Beego Session Not Passing Data to Template Automatically

问题

在使用this.GetSession("session_key")获取类型为map[string]interface{}的会话信息后,我必须显式设置上下文并对会话进行类型断言,以便将数据明确传递给模板。

// 获取会话
profile := this.GetSession("profile")

// 必须将数据添加到模板的上下文中
this.Data["nickname"] = profile.(map[string]interface{})["nickname"].(string)
this.Data["picture"] = profile.(map[string]interface{})["picture"].(string)

// 渲染模板
this.TplNames = "user.html"

会话数据(类型为map[string]interface{})如下所示:

{"nickname": "joe", "picture": "urltotheimg"}

然而,根据Beego的会话文档,似乎会话会隐式传递,无需进行任何类型断言或上下文传递(模板可以直接访问会话值,例如{{.nickname}}{{.picture}})。

这是在重定向到/user之前设置会话的控制器:

// 继承Beego的基础控制器
type MyController struct {
    beego.Controller
}

func (this *MyController) Get() {

    // 在此处获取令牌的代码

    // 获取用户信息
    client := conf.Client(oauth2.NoContext, token)
    resp, err := client.Get("https://" + domain + "/userinfo")
    if err != nil {
        this.Redirect("/error", 500)
        return
    }

    // 读取用户信息的主体
    raw, err := ioutil.ReadAll(resp.Body)
    defer resp.Body.Close()
    if err != nil {
        this.Redirect("/error", 500)
        return
    }

    // 反序列化配置文件的JSON
    var profile map[string]interface{}
    if err := json.Unmarshal(raw, &profile); err != nil {
        this.Redirect("/error", 500)
        return
    }

    // 将信息保存到会话中
    this.SetSession("profile", profile)

    // 重定向到/user
    this.Redirect("/user", 301)
}

这是/user的控制器:

type UserController struct {
    beego.Controller
}

func (this *UserController) Get() {
    // 获取保存的会话
    profile := this.GetSession("profile")

    // 如果不在此处设置模板数据,会话数据将无法在user.html中使用
    this.Data["nickname"] = profile.(map[string]interface{})["nickname"].(string)
    this.Data["picture"] = profile.(map[string]interface{})["picture"].(string)
    this.TplNames = "user.html"
}

只有这样,我才能将模板映射到数据,如下所示:

<img src="{{ .picture }}">
<p>Hello, {{ .nickname }}</p>

我相当确定需要设置模板数据,只是不确定为什么上述文档没有这样做。

如果有任何帮助,将不胜感激。

英文:

Upon getting session information of type map[string]interface{} with this.GetSession(&quot;session_key&quot;), I did have to explicitly set the context and type assert the session like this in order to explicitly pass the data to the template.

// Get the session
profile := this.GetSession(&quot;profile&quot;)

// Have to add data to the template&#39;s context
this.Data[&quot;nickname&quot;] = profile.(map[string]interface{})[&quot;nickname&quot;].(string)
this.Data[&quot;picture&quot;] = profile.(map[string]interface{})[&quot;picture&quot;].(string)

// Render template
this.TplNames = &quot;user.html&quot;

The session data (type map[string]interface{}) looks like this:

{&quot;nickname&quot;: &quot;joe&quot;, &quot;picture&quot;: &quot;urltotheimg&quot;}

However, according to the Beego's session <a href="http://beego.me/docs/mvc/controller/session.md">doc</a>, it looks like the session is passed implicitly without any need of type assertions or context passing (the template has immediate access to session values i.e. {{.nickname}} and {{.picture}})

This is the controller setting the session before redirecting to /user

// Inherit beego&#39;s base controller
type MyController struct {
    beego.Controller
}

func (this *MyController) Get() {

    // code for getting token here

    // Getting the User information
    client := conf.Client(oauth2.NoContext, token)
    resp, err := client.Get(&quot;https://&quot; + domain + &quot;/userinfo&quot;)
    if err != nil {
	    this.Redirect(&quot;/error&quot;, 500)
        return
    }

    // Reading the body for user&#39;s information
    raw, err := ioutil.ReadAll(resp.Body)
    defer resp.Body.Close()
    if err != nil {
	    this.Redirect(&quot;/error&quot;, 500)
	    return
    }

    // Unmarshalling the JSON of the Profile
	var profile map[string]interface{}
	if err := json.Unmarshal(raw, &amp;profile); err != nil {
		this.Redirect(&quot;/error&quot;, 500)
		return
	}

	// Saving the information to the session.
	this.SetSession(&quot;profile&quot;, profile)
    
	// redirect to /user
	this.Redirect(&quot;/user&quot;, 301)
}

This is the controller of "/user"

type UserController struct {
    beego.Controller
}

func (this *UserController) Get() {
    // get the saved session
    profile := this.GetSession(&quot;profile&quot;)
    
    // without setting the template data here, the session data won&#39;t be
    // available in user.html
    this.Data[&quot;nickname&quot;] = profile.(map[string]interface{})[&quot;nickname&quot;].(string)
    this.Data[&quot;picture&quot;] = profile.(map[string]interface{})[&quot;picture&quot;].(string)
    this.TplNames = &quot;user.html&quot;
}

Only this then I can map the template to the data like this:

&lt;img src=&quot;{{ .picture }}&quot;&gt;
&lt;p&gt;Hello, {{ .nickname }}&lt;/p&gt;

I'm quite sure it's necessary to set the template data. I'm just not sure why the above doc didn't do that.

Any help would be appreciated.

答案1

得分: 1

我刚刚尝试运行了Beego快速入门项目,并成功运行了它。

请确保已安装beegobee。在使用bee new projectname创建新项目后,确保编辑projectname/conf/app.conf文件并添加sessionon = true

appname = quickstart
httpport = 8080
runmode = dev
sessionon = true

我创建了一个重定向控制器:

type RedirectController struct {
    beego.Controller
}

func (c *RedirectController) Get() {
    profile := make(map[string]interface{})
    profile["nickname"] = "用户的昵称"
    profile["picture"] = "/path/to/img.jpg"

    c.SetSession("profile", profile)
    c.Redirect("/", 301)
}

主控制器:

type MainController struct {
    beego.Controller
}

func (c *MainController) Get() {
    profile := c.GetSession("profile")

    c.Data["nickname"] = profile.(map[string]interface{})["nickname"]
    c.Data["picture"] = profile.(map[string]interface{})["picture"]
    c.TplNames = "index.tpl"
}

我的index.tpl文件:

<p>昵称:{{.nickname}}</p>
<p>图片:{{.picture}}</p>

以及路由器:

func init() {
    beego.Router("/", &controllers.MainController{})
    beego.Router("/redirect", &controllers.RedirectController{})
}

我还建议您使用一个结构体来存储配置文件的值,例如:

// 定义结构体。
type Profile struct{
    Nickname string
    Picture  string
}

// 保存用于模板渲染。
this.Data["profile"] = &Profile{Nickname:"astaxie", Picture:"img.jpg"}

// 并像这样渲染它:
昵称:{{.profile.Nickname}}
图片:{{.profile.Picture}}

请确保阅读这个以了解如何进行模板渲染。希望这就是您所询问的内容,如果不是,请编辑您的问题并添加更多有用的信息,我将编辑此答案。

英文:

I just tried running the Beego quickstart project and ran it successfully.

Make sure you have both the beego and bee installed. After creating a new project with bee new projectname make sure you edit the projectname/conf/app.conf file and add the sessionon = true:

appname = quickstart
httpport = 8080
runmode = dev
sessionon = true

I created a redirect controller like:

type RedirectController struct {
	beego.Controller
}

func (c *RedirectController) Get() {
	profile := make(map[string]interface{})
	profile[&quot;nickname&quot;] = &quot;User&#39;s Nickname&quot;
	profile[&quot;picture&quot;] = &quot;/path/to/img.jpg&quot;

	c.SetSession(&quot;profile&quot;, profile)
	c.Redirect(&quot;/&quot;, 301)
}

The main controller:

type MainController struct {
	beego.Controller
}

func (c *MainController) Get() {
	profile := c.GetSession(&quot;profile&quot;)

	c.Data[&quot;nickname&quot;] = profile.(map[string]interface{})[&quot;nickname&quot;]
	c.Data[&quot;picture&quot;] = profile.(map[string]interface{})[&quot;picture&quot;]
	c.TplNames = &quot;index.tpl&quot;
}

My index.tpl file:

&lt;p&gt;Nickname: {{.nickname}}&lt;/p&gt;
&lt;p&gt;Picture: {{.picture}}&lt;/p&gt;

And the router:

func init() {
	beego.Router(&quot;/&quot;, &amp;controllers.MainController{})
	beego.Router(&quot;/redirect&quot;, &amp;controllers.RedirectController{})
}

I would also recommend you to use a structure to store the profile values like:

// Define struct.
type Profile struct{
    Nickname string
    Picture  string
}

// Save it for template rendering.
this.Data[&quot;profile&quot;] = &amp;Profile{Nickname:&quot;astaxie&quot;, Picture:&quot;img.jpg&quot;}

// And render it like this:
Nickname: {{.profile.Nickname}}
Picture:  {{.profile.Picture}}

Make sure to read this to understand how template rendering is done. I hope this is what you were asking for, if not, please edit your question and add more helpful information and I will edit this answer.

huangapple
  • 本文由 发表于 2015年12月9日 06:09:26
  • 转载请务必保留本文链接:https://go.coder-hub.com/34167007.html
匿名

发表评论

匿名网友

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

确定