为了账号安全,请及时绑定邮箱和手机立即绑定

如何修复 azure-storage-blob-go 中的“验证失败:字段“body”不存在”错误?

如何修复 azure-storage-blob-go 中的“验证失败:字段“body”不存在”错误?

Go
萧十郎 2023-08-07 15:15:05
我正在尝试将多部分文件上传到 blob AppendBlock(),但出现此错误:-> github.com/Azure/azure-pipeline-go/pipeline.NewError, /home/makoto/go/pkg/mod/github.com/!azure/azure-pipeline-go@v0.2.1/pipeline/error.go:159validation failed: parameter=body constraint=Null value=multipart.sectionReadCloser{SectionReader:(*io.SectionReader)(0xc000643a40)} details: field "body" doesn't existfunc 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如果我传递 a而不是多部分文件,它可以正常工作而不会引发错误。为什么会出现此错误?我该如何修复它?
查看完整描述

2 回答

?
吃鸡游戏

TA贡献1829条经验 获得超7个赞

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


错误源于这里。在此函数的正上方,您可以看到 的值multipart.File采用case reflect.Struct:switch 情况。如果你传递 a string.Builder,它就会采用该case reflect.Ptr:路径。当我们传入 a 时,我们可以multipart.File通过将其包装在结构体中并获取其指针来强制执行此路径。


wrapper := &struct{ io.ReadSeeker }{file}

_, err = appendBlobURL.AppendBlock(context.Background(), wrapper, azblob.AppendBlobAccessConditions{}, nil)

return err


查看完整回答
反对 回复 2023-08-07
?
青春有我

TA贡献1784条经验 获得超8个赞

事实证明,multipart.File当首先使用 检索不同的表单值r.FormFile("someKey"),然后调用r.ParseMultipartForm(),然后使用时,确实是 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 问题?您的解决方案确实是一种解决方法,但是如上所述,我能够通过确保表单处理顺序正确来完全防止该问题。


查看完整回答
反对 回复 2023-08-07
  • 2 回答
  • 0 关注
  • 130 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信