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

我正在尝试将多部分文件上传到 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: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如果我传递 a而不是多部分文件,它可以正常工作而不会引发错误。


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


萧十郎
浏览 96回答 2
2回答

吃鸡游戏

这是我在 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

青春有我

事实证明,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 问题?您的解决方案确实是一种解决方法,但是如上所述,我能够通过确保表单处理顺序正确来完全防止该问题。
打开App,查看更多内容
随时随地看视频慕课网APP