登录
首页 >  Golang >  Go问答

解决 azure-storage-blob-go 中的“body字段不存在”验证失败问题

来源:stackoverflow

时间:2024-02-27 16:57:24 452浏览 收藏

欢迎各位小伙伴来到golang学习网,相聚于此都是缘哈哈哈!今天我给大家带来《解决 azure-storage-blob-go 中的“body字段不存在”验证失败问题》,这篇文章主要讲到等等知识,如果你对Golang相关的知识非常感兴趣或者正在自学,都可以关注我,我会持续更新相关文章!当然,有什么建议也欢迎在评论留言提出!一起学习!

问题内容

我尝试使用 appendblock() 将多部分文件上传到 blob,但收到此错误:

-> github.com/azure/azure-pipeline-go/pipeline.newerror, /home/makoto/go/pkg/mod/github.com/!azure/[email protected]/pipeline/error.go:159
validation failed: parameter=body constraint=null value=multipart.sectionreadcloser{sectionreader:(*io.sectionreader)(0xc000643a40)} details: field "body" doesn't exist
func Upload(file multipart.File) error {
    credential, err := azblob.NewSharedKeyCredential("credential strings", "")
    if err != nil {
        return err
    }

    u, _ := url.Parse("blob url")
    appendBlobURL := azblob.NewAppendBlobURL(
        *u,
        azblob.NewPipeline(credential, azblob.PipelineOptions{}),
    )

    _, err = appendBlobURL.Create(
        context.Background(),
        azblob.BlobHTTPHeaders{},
        azblob.Metadata{},
        azblob.BlobAccessConditions{},
    )
    if err != nil {
        return err
    }

    _, err = appendBlobURL.AppendBlock(context.Background(), file, azblob.AppendBlobAccessConditions{}, nil)
    // validation failed: parameter=body constraint=Null value=multipart.sectionReadCloser{SectionReader:(*io.SectionReader)(0xc000643a40)}
    // details: field "body" doesn't exist
    return err
}

如果我传递 string.builder 而不是多部分文件,它不会引发错误。

为什么会出现此错误?我该如何修复它?


解决方案


这是我在 go 中遇到的最愚蠢的错误之一,因此希望这可以帮助遇到此问题的任何人。

错误源自 here。在此函数的正上方,您可以看到 multipart.file 的值采用 casereflect.struct: 开关大小写。如果您改为传递 string.builder,则它将采用 case reflect.ptr: 路径。当我们传入 multipart.file 时,我们可以通过将其包装在结构体中并获取其指针来强制使用此路径。

wrapper := &struct{ io.readseeker }{file}
_, err = appendbloburl.appendblock(context.background(), wrapper, azblob.appendblobaccessconditions{}, nil)
return err

事实证明,当第一次使用 r.formfile("somekey") 检索不同的表单值,然后调用 r.parsemultipartform() ,然后使用时,multipart.file 确实是 struct 类型

type Block struct {
  File *multipart.File
  Name *string
}
func someFunction(r *http.Request, w http.ResonseWriter) error {
  r.Body = http.MaxBytesReader(w, r.Body, maxUploadSize)
  if err := r.ParseMultipartForm(maxMemory); err != nil {
    return err
  }
  someFunction1(r)
}
func someFunction1(r *http.Request) {
  var f multipart.File
  someFunction2(r, &f)

  name := "block1"
  b := Block{
    File: &f,
    Name: &name,
  }

  someUploadFunc(&b, "cn")
}
func someFunction2(r *http.Request, *v multipart.File) error {
  f := r.FormFile("fileKey")
  *v = f
  return nil
}
func someUploadFunc(b *Block, cn string) {
  curl := bs.NewContainerURL(cn)
  burl := curl.NewBlockBlobURL(*b.Name)
  lac := azblob.LeaseAccessConditions{}

  r, err := burl.StageBlock(ur.Context, "123", *b.File, lac, nil)
  ...
}

引用指向文件的指针。在此场景中,*v 的类型将为 struct。但是,通过将处理顺序更改为首先调用 r.parsemultipartform(),然后 r.formfile("somekey"),然后 r.formfile("filekey")*v 的类型为 multipart.file

我不太清楚为什么会出现这种情况。看起来是 golang 问题?您的解决方案确实是一种解决方法,但是如上所述,我能够通过确保表单处理顺序正确来完全防止该问题。

文中关于的知识介绍,希望对你的学习有所帮助!若是受益匪浅,那就动动鼠标收藏这篇《解决 azure-storage-blob-go 中的“body字段不存在”验证失败问题》文章吧,也可关注golang学习网公众号了解相关技术文章。

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>