输入不是有效的Base-64字符串,因为它包含非Base 64字符


97

我有一个REST服务,可以将文件转换为Byte数组,然后转换为Base64字符串,然后读取文件并将其发送到另一个控制台应用程序。该部分可以工作,但是当应用程序接收到相同的流时,它将受到操纵,并且不再是有效的Base64字符串。流中引入了一些垃圾字符。

将流转换回Byte时收到的异常是

输入内容不是有效的Base-64字符串,因为它包含非Base 64字符,两个以上的填充字符或填充字符中的非空白字符

服务中:

[WebGet(UriTemplate = "ReadFile/Convert", ResponseFormat = WebMessageFormat.Json)]  
public string ExportToExcel()
  {
      string filetoexport = "D:\\SomeFile.xls";
      byte[] data = File.ReadAllBytes(filetoexport);
      var s = Convert.ToBase64String(data);
      return s;
  }

申请时:

       var client = new RestClient("http://localhost:56877/User/");
       var request = new RestRequest("ReadFile/Convert", RestSharp.Method.GET);
       request.AddHeader("Accept", "application/Json");
       request.AddHeader("Content-Type", "application/Json");
       request.OnBeforeDeserialization = resp => {resp.ContentType =    "application/Json";};
       var result = client.Execute(request);
       byte[] d = Convert.FromBase64String(result.Content); 

4
可能与此有关Encoding
Alex Filipovici

1
您知道要插入什么“垃圾字符”吗?
Jim Mischel

更新的代码很有帮助。现在,我们需要查看您发送的字符串(即s在服务上)和接收到的内容(即result.content。您不需要发布整个字符串,只需发布​​第一个变形的字符即可(或者,如果仍然太长的话) ,一些子字符串显示发送了什么,接收到了什么。)
Jim Mischel 2013年

@JimMischel是的,我注意到'/'被替换为'\ /'
Rohit Verma

@RohitVerma对于要替换的斜杠,是在原始HTML内容中(Fiddler会告诉您)还是在其中result.Content?这将告诉您问题出在服务器还是客户端。
Joe Enos

Answers:


92

检查图像数据开头是否包含一些标题信息:

imageCode = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAABkC...

这将导致上述错误。

只要删除逗号(包括第一个逗号)之前的所有内容,就可以了。

imageCode = "iVBORw0KGgoAAAANSUhEUgAAAMgAAABkC...

莫名其妙地有这个确切的问题。逻辑是,如果data:存在,则删除所有内容。am 现在工作。
Maxime Rouiller

var cleanerBase64 = imageCode.Substring(22); //删除数据:image / png; base64
mejiamanuel57

3
只需一点代码即可提供帮助……如果(this.imageCode.Contains(','))this.imageCode = this.imageCode.Substring(this.imageCode.IndexOf(“,”)+ 1, this.imageCode.Length-(this.imageCode.IndexOf(“,”)+ 1));
Toby Simmerling

我会使用:.Split(',')[1]
Verthosa

str.Substring(str.LastIndexOf(',') + 1)应该这样做。
阿里森

64

很可能将其转换为修改后的Base64,其中+/字符更改为-_。参见http://en.wikipedia.org/wiki/Base64#Implementations_and_history

在这种情况下,您需要将其更改回:

string converted = base64String.Replace('-', '+');
converted = converted.Replace('_', '/');

1
我完成了...。谢谢!!用适当的字符替换字符。但这是一个具体的解决方案吗?我的意思是我该如何保证对于所有文件来说,这将是要替换的字符?
Rohit Verma,

2
@RohitVerma:我不知道。您需要找出这些字符在哪里更改,并确定是否有可能更改其他任何字符。我对RestSharp不熟悉,所以在这里我无法提供任何建议。如果我的回答回答了您的问题,通常将其标记为已接受的答案。(单击左侧答案旁边的选中标记。)
Jim Mischel

天哪,谢谢!这并添加必要的填充“ =”字符解决了我的问题。Azure的Key Vault REST API中的解密功能需要此过程,并且不会对其进行记录。
used2could

33

我们可以删除值前面的不必要的字符串输入。

string convert = hdnImage.Replace("data:image/png;base64,", String.Empty);

byte[] image64 = Convert.FromBase64String(convert);

这个解决方案对我有用。但这是专门针对png图像的。是否有任何通用语法可以代替所有图像扩展名?
卡兰·德赛

1
我现在阅读您的评论。我不尝试这样做,但是您可以使用:hdnImage.Replace(“ data:image / png; base64,”,String.Empty).Replace(“ data:image / jpg; base64,”,String.Empty).Replace( “ data:image / bmp; base64,”,String.Empty); 再次,我不尝试这个。请尝试为我写信。我会改变。
哈桑金枪鱼Oruç16年

5

万一您不知道所上传图片的类型,只需删除其base64标题即可:

 var imageParts = model.ImageAsString.Split(',').ToList<string>();
 //Exclude the header from base64 by taking second element in List.
 byte[] Image = Convert.FromBase64String(imageParts[1]);

拆分并列出?使用宁可使用IndexOf和子字符串
Emmanuel Gleizer


4

由于您要以JSON的形式返回字符串,因此该字符串将在原始响应中包含左引号和右引号。因此,您的回复应该类似于:

"abc123XYZ=="

或其他...您可以尝试与Fiddler确认。

我的猜测是,这result.Content是原始字符串,包括引号。如果是这种情况,则result.Content需要先反序列化才能使用它。


您是正确的,其中包括“”,但这里的要点是,除了添加这些引号外,其他字符也将被替换。
Rohit Verma,

使用JSON序列化器反序列化该字符串将同时处理引号和转义的斜杠。一些JSON序列化程序会用反斜杠转义正斜杠-使用反序列化程序会将\ /改回纯正/,以便获得有效的base-64。由于您正在接收JSON,因此正确地解析JSON始终是一个好主意,即使它只是一个简单的字符串也是如此。
Joe Enos

3

我按照您所描述的安排了相似的上下文,并且遇到了相同的错误。我设法得到它的工作通过移除"从一开始就和内容的末端,通过更换 \//

这是代码片段:

var result = client.Execute(request);
var response = result.Content
    .Substring(1, result.Content.Length - 2)
    .Replace(@"\/","/");
byte[] d = Convert.FromBase64String(response);

或者,您可以考虑使用XML作为响应格式:

[WebGet(UriTemplate = "ReadFile/Convert", ResponseFormat = WebMessageFormat.Xml)]  
public string ExportToExcel() { //... }

在客户端:

request.AddHeader("Accept", "application/xml");
request.AddHeader("Content-Type", "application/xml");
request.OnBeforeDeserialization = resp => { resp.ContentType = "application/xml"; };

var result = client.Execute(request);
var doc = new System.Xml.XmlDocument();
doc.LoadXml(result.Content);
var xml = doc.InnerText;
byte[] d = Convert.FromBase64String(xml);

3
var spl = item.Split('/')[1];
var format =spl.Split(';')[0];           
stringconvert=item.Replace($"data:image/{format};base64,",String.Empty);

7
尽管此代码可能会解决这个问题,一个很好的答案也应该解释什么代码的作用和如何它可以帮助。
BDL

1

正如Alex Filipovici所提到的,该问题是错误的编码。我读取的文件是,UTF-8-BOM并在上引发了上述错误Convert.FromBase64String()。改成UTF-8没有问题的工作。


1

有时它以双引号开头,大多数情况是从dotNetCore 2调用API来获取文件时

string string64 = string64.Replace(@"""", string.Empty);
byte[] bytes = Convert.ToBase64String(string64);

1
无法从字符串转换为字节[]
Urasquirrel,

1

字符串可能像这样data:image/jpeg;base64,/9j/4QN8RXh... 首先拆分/并获得第二个令牌。

var StrAfterSlash = Face.Split('/')[1];

然后拆分以;获取第一个标记,该标记将为格式。就我而言,它是jpeg。

var ImageFormat =StrAfterSlash.Split(';')[0];

然后删除data:image/jpeg;base64,所收集格式的行

CleanFaceData=Face.Replace($"data:image/{ImageFormat };base64,",string.Empty);

1

通过正则表达式删除不必要的字符串

Regex regex=new Regex(@"^[\w/\:.-]+;base64,");
base64File=regex.Replace(base64File,string.Empty);
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.