【问题标题】:Cannot convert HttpPostedFileBase to Byte[]无法将 HttpPostedFileBase 转换为 Byte[]
【发布时间】:2015-01-26 22:51:25
【问题描述】:

我有一个接收 HttpPostedFileBase(.jpg 或 .png 等)的控制器。

public ActionResult SaveImage(HttpPostedFileBase ImageData)
{
  //code
}

ImageData 成为具有以下属性的 System.Web.HttpPostedFileWrapper 对象:

ContentLength: 71945
ContentType: "image/png"
FileName: "foo.png"
InputStream: {System.Web.HttpInputStream}

我没有任何问题将 ImageData 转换为 Image,然后将 Image 转换为 byte[],然后转换为 base64 字符串 - 但我尝试使用以下代码:

byte[] imgData;

using (Stream inputStream = ImageData.InputStream)
{
    MemoryStream memoryStream = inputStream as MemoryStream;
    if (memoryStream == null)
    {
        memoryStream = new MemoryStream();
        inputStream.CopyTo(memoryStream);
    }

    imgData = memoryStream.ToArray();
}

memoryStream 在调用imgData = memoryStream.ToArray(); 时始终为空,因此imgData 最终也为空。

我很难理解为什么我不能将此 InputStream 读入 MemoryStream。 InputStream 似乎很好,除了抛出timeouts are not supported on this stream 的 readTimeout 和 writeTimeout 属性。我做错了什么,为什么我不能将 ImageData 转换为 byte[]?

以防万一,这是我的 AJAX 调用。 contentTypeprocessData 选项设置为 false 会不会是个问题?

$.ajax({
    url: 'SaveImage',
    data: formData,
    type: "POST",
    contentType: false,
    processData: false,
    beforeSend: function () {
        $("#loadingScreenModal").modal('toggle');
    },
    success: function (data) {
        // etc.
    }
});

更新:我通过将HttpPostedFileBase 转换为Image,然后将Image 转换为byte[] 解决了这个问题,但我仍然有兴趣弄清楚为什么我必须执行这个中间步骤。

Image i = Image.FromStream(ImageData.InputStream, true, true);
byte[] imgData = imageToByteArray(thumb);

public byte[] imageToByteArray(Image imageIn)
{
    MemoryStream ms = new MemoryStream();
    imageIn.Save(ms, System.Drawing.Imaging.ImageFormat.Gif);
    return ms.ToArray();
}

更新 #2: 我认为我的代码的问题可能是 if (memoryStream == null) 块中的代码从未被调用。

【问题讨论】:

  • memoryStream 在该行永远不会为空。
  • 阅读这里如何阅读流:msdn.microsoft.com/en-us/library/…
  • @JoeEnos 我更新了我的问题以反映它是空的,而不是空的。
  • 您的代码按原样为我工作。如果您可以在表单中包含 HTML 的相关部分,以及您可能在 SaveImage 方法中遗漏的任何内容,那将很有帮助。
  • @Muflix 一个 Image 对象 - 看看 imageToByteArray 函数的参数。

标签: c# asp.net asp.net-mvc


【解决方案1】:

您可以使用BinaryReader 类将字符串读入字节数组:

byte[] imgData;

using (var reader = new BinaryReader(ImageData.InputStream))
{
    imgData = reader.ReadBytes(ImageData.ContentLength);
}

【讨论】:

  • 感谢您的回复,但这对我不起作用。据我所知,我发布的代码应该将 HttpPostedFileBase 转换为 MemoryStream,但事实并非如此。显然,我的理解存在差距,我有兴趣试图弄清楚。
  • 你不能从一种类型的流“转换”到另一种类型的流——你必须从一种流中读取并写入另一种(这就是CopyTo 所做的。你真的 需要MemoryStream 或者这只是获取底层字节的一种方式?为什么答案对你不起作用?
  • 我不知道为什么答案对我不起作用,因为我不完全理解 MemoryStreams 的工作方式。我只对底层字节感兴趣;我想将图像保存到数据库中varbinary(max)
【解决方案2】:

我有类似的代码,其中我将流直接读入一个字节[],如下所示:

var streamLength = ImageData.InputStream.Length;
var imageBytes = new byte[streamLength];
ImageData.InputStream.Read(imageBytes, 0, imageBytes.Length);

然后我将 imageBytes 作为varbinary(MAX) 存储到数据库中。似乎工作正常。

【讨论】:

    【解决方案3】:

    答案最终是memoryStream == null 检查,正如 JoeEnos 建议的那样。 MemoryStream 在此检查正上方的行上被实例化 - 所以它不应该为空 - 而应该使用 if (memoryStream.Length == 0) 来检查。

    【讨论】:

      【解决方案4】:

      型号代码

      public class AdminDetailsModel
      {
          public byte[] AdminImage { get; set; }
       }
      

      查看代码

      @using (Html.BeginForm("Create", "AdminDetails", FormMethod.Post, new { enctype = "multipart/form-data" }))
      {   
          <div class="form-group">
              @Html.LabelFor(model => model.AdminImage, new { @class = "control-label col-md-2" })
              <div class="col-md-10">
                  <input type="file" name="ImageData" id="ImageData" />                              
              </div>
          </div>
          <div class="form-group">
              <div class="col-md-offset-2 col-md-10">
                  <input type="submit" value="Create" class="btn btn-default" />
              </div>
          </div>
      

      在你的控制器中这样的代码

      public ActionResult Create(AdminDetailsModel viewmodel)
      {
          if (ModelState.IsValid)
          {
          HttpPostedFileBase file = Request.Files["ImageData"];
          viewmodel.Image = ConvertToByte(file);
          db.YourDbContextSet.Add(viewmodel);
          db.SaveChanges();
          }
      }
      
      public byte[] ConvertToByte(HttpPostedFileBase file)
          {
              byte[] imageByte = null;
              BinaryReader rdr = new BinaryReader(file.InputStream);
              imageByte = rdr.ReadBytes((int)file.ContentLength);
              return imageByte;
          }
      

      希望这会有所帮助

      【讨论】:

      • 谢谢 Prakash,但这并不能真正解决我的问题。我不太关心 View,您在示例中给出的 ViewModel 假设 HttpPostedFileBase 已经是一个字节 []。我试图弄清楚为什么我必须采取中间步骤并将HttpPostedFileBase 转换为Image,然后再将其转换为byte[]
      猜你喜欢
      • 2011-12-12
      • 1970-01-01
      • 2018-09-05
      • 2016-12-26
      • 2016-01-29
      • 1970-01-01
      • 2021-08-26
      • 1970-01-01
      相关资源
      最近更新 更多