英文:
Id is Returning 0 for Rest API with Go
问题
我一直在尝试使用Go构建一些简单的后端REST API,使用Google App Engine和其数据存储,并在前端使用AngularJS。我能够让所有东西都正常工作,但是编辑功能有问题。我不确定为什么JSON无法正确解组。
结构体:
type Article struct {
Key int64 `json:"Key" datastore:"-"`
Title string
Text string `datastore:",noindex"`
Author string
Tags string
Posted time.Time
}
当加载文章时,我使用数据存储中的id值填充Key属性。例如:5593215650496512
我将该字段保存在表单的隐藏输入中,并通过HTTP Post将表单内容作为JSON提交到Go后端。
在提交之前,我可以看到Key属性保存了正确的值。以下是表单的代码:
<form name="articleForm" ng-submit="saveArticle(article)">
<fieldset>
<input type="hidden" name="key" ng-value="article.Key" />
<div class="form-group">
<input class="form-control" ng-model="article.Title" placeholder="Title" name="title" type="text" required autofocus />
<div class="alert alert-danger" ng-show="articleForm.Title.$invalid && articleForm.Title.$dirty">
<ul>
<li ng-show="articleForm.title.$error.required">this field is required</li>
</ul>
</div>
</div>
<div class="form-group">
<wysiwyg
name="text"
textarea-id="articleText"
textarea-class="form-control"
textarea-height="180px"
textarea-name="articleText"
ng-model="article.Text"
enable-bootstrap-title="true"
textarea-required>
</wysiwyg>
<div class="alert alert-danger" ng-show="articleForm.text.$invalid && articleForm.text.$dirty">
<ul>
<li ng-show="articleForm.text.$error.required">this field is required</li>
</ul>
</div>
</div>
<div class="form-group">
<tags-input ng-model="tags"></tags-input>
</div>
<button type="submit" ng-disabled="!articleForm.$valid" class="btn btn-primary">
Save Article
</button>
</fieldset>
</form>
在HTTP Post之前,$scope.article对象的值如下:
Author: "Matt Ridley"
Key: "5593215650496512"
Posted: "2015-06-29T12:57:20.833525Z"
Tags: "test,so-cool"
Text: "<div>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer nec odio. Praesent libero. Sed cursus ante dapibus diam. Sed nisi. Nulla quis sem at nibh elementum imperdiet. Duis sagittis ipsum. Praesent mauris. Fusce nec tellus sed augue semper porta. Mauris massa. Vestibulum lacinia arcu eget nulla. </div>"
Title: "Example Article 8"
然而,Key属性仍然为0。我可以将该值作为单个id值传递,用于删除和加载,没有问题。
加载只使用id的代码(有效):
var id int64
json.Unmarshal(body, &id)
c.Infof("ID: %v", id)
key := datastore.NewKey(c, "Article", "", id, nil)
编辑带有其他值的代码(无效,id为0):
var article Article
json.Unmarshal(body, &article)
c.Infof("Article:%g", article)
c.Infof("Body:" + string(body))
c.Infof("Key:%v", article.Key)
article.Posted = time.Now()
以下是json.Unmarshal后结构体的转储:
2015/06/29 03:04:08 INFO: Article:{%!g(int64=0) %!g(string=Example Article 8) %!g(string=<div>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer nec odio. Praesent libero. Sed cursus ante dapibus diam. Sed nisi. Nulla quis sem at nibh elementum imperdiet. Duis sagittis ipsum. Praesent mauris. Fusce nec tellus sed augue semper porta. Mauris massa. Vestibulum lacinia arcu eget nulla. </div>) %!g(string=Matt Ridley) %!g(string=test,so-cool) {%!g(int64=63570890170) %!g(int32=842211000) %!g(*time.Location=&{UTC [] [] 0 0 <nil>})}}
Key的日志记录如下:
2015/06/29 03:04:08 INFO: Key:0
body的转储:
2015/06/29 14:00:34 INFO: Body:{"Key":"5593215650496512","Title":"Example Article 8","Text":"<div>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer nec odio. Praesent libero. Sed cursus ante dapibus diam. Sed nisi. Nulla quis sem at nibh elementum imperdiet. Duis sagittis ipsum. Praesent mauris. Fusce nec tellus sed augue semper porta. Mauris massa. Vestibulum lacinia arcu eget nulla. </div>","Author":"Matt Ridley","Tags":"test,so-cool","Posted":"2015-06-29T13:28:06.168062Z"}
我已经为此问题苦苦思索了几天,所以任何见解都将不胜感激。谢谢!
英文:
I have been trying to build some simple backend REST API using Go using the Google App Engine and its datastore and AngularJS on the frontend. I was able to get everything working but the edit. And I am not sure why the JSON is not un-marshaling correctly.
Struct:
type Article struct {
Key int64 `json:"Key" datastore:"-"`
Title string
Text string `datastore:",noindex"`
Author string
Tags string
Posted time.Time
}
When I load the article, I populate the Key property with the id value from the datastore. Example: 5593215650496512
I keep that field in a hidden input on my form, and submit the form's content as JSON through an HTTP Post to the Go backend.
Before the submit, I can see that the Key holds the proper value. Here is the form though:
<form name="articleForm" ng-submit="saveArticle(article)">
<fieldset>
<input type="hidden" name="key" ng-value="article.Key" />
<div class="form-group">
<input class="form-control" ng-model="article.Title" placeholder="Title" name="title" type="text" required autofocus />
<div class="alert alert-danger" ng-show="articleForm.Title.$invalid && articleForm.Title.$dirty">
<ul>
<li ng-show="articleForm.title.$error.required">this field is required</li>
</ul>
</div>
</div>
<div class="form-group">
<wysiwyg
name="text"
textarea-id="articleText"
textarea-class="form-control"
textarea-height="180px"
textarea-name="articleText"
ng-model="article.Text"
enable-bootstrap-title="true"
textarea-required>
</wysiwyg>
<div class="alert alert-danger" ng-show="articleForm.text.$invalid && articleForm.text.$dirty">
<ul>
<li ng-show="articleForm.text.$error.required">this field is required</li>
</ul>
</div>
</div>
<div class="form-group">
<tags-input ng-model="tags"></tags-input>
</div>
<button type="submit" ng-disabled="!articleForm.$valid" class="btn btn-primary">
Save Article
</button>
</fieldset>
</form>
The $scope.article object right before the http post:
> Author: "Matt Ridley"
Key: "5593215650496512"
Posted: "2015-06-29T12:57:20.833525Z"
Tags: "test,so-cool"
Text: "<div>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer nec odio. Praesent libero. Sed cursus ante dapibus diam. Sed nisi. Nulla quis sem at nibh elementum imperdiet. Duis sagittis ipsum. Praesent mauris. Fusce nec tellus sed augue semper porta. Mauris massa. Vestibulum lacinia arcu eget nulla. </div>"
Title: "Example Article 8"
However, the Key property remains 0. I am able to pass that value in as a single id value with no issue for delete and load.
Code for loading just the id (this was the load version, it works):
var id int64
json.Unmarshal(body, &id)
c.Infof("ID: %v", id)
key := datastore.NewKey(c, "Article", "", id, nil)
Code for the edit with additional values (does not work, id = 0):
var article Article
json.Unmarshal(body, &article)
c.Infof("Article:%g", article)
c.Infof("Body:" + string(body))
c.Infof("Key:%v", article.Key)
article.Posted = time.Now()
Here is a dump of the struct after json.Unmarshal:
> 2015/06/29 03:04:08 INFO: Article:{%!g(int64=0) %!g(string=Example Article 8)
> %!g(string=<div>Lorem ipsum dolor sit amet, consectetur adipiscing
> elit. Integer nec odio. Praesent libero. Sed cursus ante dapibus diam.
> Sed nisi. Nulla quis sem at nibh elementum imperdiet. Duis sagittis
> ipsum. Praesent mauris. Fusce nec tellus sed augue semper porta.
> Mauris massa. Vestibulum lacinia arcu eget
> nulla. </div>) %!g(string=Matt Ridley)
> %!g(string=test,so-cool) {%!g(int64=63570890170) %!g(int32=842211000)
> %!g(*time.Location=&{UTC [] [] 0 0 <nil>})}}
Key is logging as...
> 2015/06/29 03:04:08 INFO: Key:0
The body dump:
> 2015/06/29 14:00:34 INFO: Body:{"Key":"5593215650496512","Title":"Example Article 8","Text":"<div>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer nec odio. Praesent libero. Sed cursus ante dapibus diam. Sed nisi. Nulla quis sem at nibh elementum imperdiet. Duis sagittis ipsum. Praesent mauris. Fusce nec tellus sed augue semper porta. Mauris massa. Vestibulum lacinia arcu eget nulla. </div>","Author":"Matt Ridley","Tags":"test,so-cool","Posted":"2015-06-29T13:28:06.168062Z"}
I have been banging my head on this for a few days, so any insight would be appreciated. Thanks!
答案1
得分: 1
你在对文章进行解组(Unmarshal)时忽略了错误。你应该看到json: cannot unmarshal string into Go value of type int64
的错误提示,因为在请求体中的Key
值被格式化为字符串。
如果这是你期望的结果,你可以通过在标签中添加string
选项来告诉json包使用它:
type Article struct {
Key int64 `json:"Key,string" datastore:"-"`
Title string
Text string `datastore:",noindex"`
Author string
Tags string
Posted time.Time
}
英文:
You're ignoring the error when you Unmarshal into your Article. You should see json: cannot unmarshal string into Go value of type int64
, because the Key
value in the body is being formatted as a string.
If it is what you expect, then you can tell the json package to make use of it by adding the string
option to the tag:
type Article struct {
Key int64 `json:"Key,string" datastore:"-"`
Title string
Text string `datastore:",noindex"`
Author string
Tags string
Posted time.Time
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论