Đầu vào không phải là một chuỗi Base-64 hợp lệ vì nó chứa một ký tự 64 không phải base


98

Tôi có một dịch vụ REST đọc một tệp và gửi nó đến một ứng dụng bảng điều khiển khác sau khi chuyển đổi nó thành mảng Byte và sau đó thành chuỗi Base64. Phần này hoạt động, nhưng khi nhận được cùng một luồng tại ứng dụng, nó sẽ bị thao túng và không còn là chuỗi Base64 hợp lệ. Một số nhân vật rác đang được đưa vào luồng.

Ngoại lệ nhận được khi chuyển đổi luồng trở lại Byte là

Đầu vào không phải là chuỗi Base-64 hợp lệ vì nó chứa một ký tự 64 không phải base, nhiều hơn hai ký tự đệm hoặc một ký tự khoảng trắng không phải giữa các ký tự đệm

Tại dịch vụ:

[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;
  }

Tại ứng dụng:

       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
Có lẽ điều này phải làm với Encoding.
Alex Filipovici 27/02/13

1
Bạn có biết những "ký tự rác" nào đang được chèn vào không?
Jim Mischel

Mã được cập nhật rất hữu ích. Bây giờ chúng tôi cần xem chuỗi mà bạn gửi (tức là strên dịch vụ) và nội dung nhận được (tức là result.content. Bạn không cần phải đăng toàn bộ chuỗi, chỉ cần tối đa ký tự bị xáo trộn đầu tiên (hoặc nếu vẫn quá dài , một số chuỗi con mà hiển thị những gì đã được gửi và những gì đã nhận được).
Jim Mischel

@JimMischel vâng, tôi nhận thấy rằng '/' đang được thay thế bằng '\ /'
Rohit Verma

@RohitVerma Đối với dấu gạch chéo được thay thế, đó là trong nội dung HTML thô (Fiddler sẽ cho bạn biết), hay trong result.Content? Điều đó sẽ cho bạn biết nếu vấn đề là với máy chủ hay máy khách.
Joe Enos

Câu trả lời:


93

Kiểm tra xem dữ liệu hình ảnh của bạn có chứa một số thông tin tiêu đề ở đầu hay không:

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

Điều này sẽ gây ra lỗi trên.

Chỉ cần xóa mọi thứ phía trước và bao gồm cả dấu phẩy đầu tiên, và bạn đã sẵn sàng.

imageCode = "iVBORw0KGgoAAAANSUhEUgAAAMgAAABkC...

Đã có vấn đề chính xác này bằng cách nào đó. Logic là loại bỏ mọi thứ sau ,nếu data:có. Bam. Đang làm việc.
Maxime Rouiller

var cleanBase64 = imageCode.Substring (22); // xóa dữ liệu: image / png; base64
mejiamanuel57,

3
Chỉ cần một chút mã để trợ giúp ...... if (this.imageCode.Contains (',')) this.imageCode = this.imageCode.Substring (this.imageCode.IndexOf (",") + 1, this.imageCode.Length - (this.imageCode.IndexOf (",") + 1));
Toby Simmerling

Tôi sẽ sử dụng: .Split (',') [1]
Verthosa 22/07/19

str.Substring(str.LastIndexOf(',') + 1)Hãy làm nó.
Alisson

65

Rất có thể nó được chuyển đổi thành Base64 đã được sửa đổi, nơi các ký tự +/được đổi thành -_. Xem http://en.wikipedia.org/wiki/Base64#Implementations_and_history

Nếu đúng như vậy, bạn cần thay đổi lại:

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

1
Tôi đã hoàn thành việc này .... Cảm ơn bạn !! Thay thế các ký tự bằng những ký tự thích hợp. Nhưng đây có phải là một giải pháp cụ thể? ý tôi là làm thế nào tôi có thể đảm bảo rằng đối với tất cả các tệp, đây sẽ là ký tự được thay thế?
Rohit Verma

2
@RohitVerma: Tôi không biết. Bạn cần tìm hiểu nơi các ký tự đó đang được thay đổi và xác định xem nó có khả năng thay đổi bất kỳ ký tự nào khác hay không. Tôi không quen thuộc với RestSharp, vì vậy tôi không thể đưa ra bất kỳ lời khuyên nào ở đó. Nếu câu trả lời của tôi trả lời câu hỏi của bạn, theo thông lệ, bạn nên đánh dấu nó là câu trả lời được chấp nhận. (Nhấp vào dấu kiểm bên cạnh câu trả lời ở bên trái.)
Jim Mischel

OMG Cảm ơn bạn! Điều này và thêm ký tự đệm "=" cần thiết đã giải quyết được vấn đề của tôi. Hàm giải mã trong API REST Key Vault của Azure cần quá trình này và không ghi lại nó.
used2could

33

Chúng ta có thể xóa đầu vào chuỗi không cần thiết ở phía trước giá trị.

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

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

Giải pháp này đã làm việc cho tôi. Nhưng điều này đặc biệt dành cho hình ảnh png. Có cú pháp tổng quát nào thay thế tất cả các loại phần mở rộng hình ảnh không?
Karan Desai

1
tôi đọc bình luận của bạn bây giờ. tôi không thử cái này nhưng bạn có thể sử dụng cái này: hdnImage.Replace ("data: image / png; base64,", String.Empty) .Replace ("data: image / jpg; base64,", String.Empty) .Replace ( "data: image / bmp; base64,", String.Empty); một lần nữa, tôi không thử cái này. hãy thử và viết cho tôi. Tôi sẽ thay đổi.
Hasan Tuna Oruç

5

Đề phòng trường hợp bạn không biết loại hình ảnh đã tải lên và bạn chỉ cần xóa base64tiêu đề của nó :

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

tách và thành danh sách? sử dụng chứ không phải IndexOf và chuỗi
Emmanuel Gleizer

xem demeranville.com/… và câu hỏi cũng được đăng ở đây: stackoverflow.com/questions/35388181/…
Emmanuel Gleizer,

4

Vì bạn đang trả về một chuỗi dưới dạng JSON, nên chuỗi đó sẽ bao gồm dấu ngoặc kép mở và đóng trong phản hồi thô. Vì vậy, phản hồi của bạn có thể sẽ giống như sau:

"abc123XYZ=="

hoặc bất cứ điều gì ... Bạn có thể thử xác nhận điều này với Fiddler.

Tôi đoán rằng đó result.Contentlà chuỗi thô, bao gồm cả dấu ngoặc kép. Nếu đúng như vậy, result.Contentbạn sẽ cần phải giải mã trên không trước khi có thể sử dụng.


bạn nói đúng, điều này bao gồm "" nhưng vấn đề ở đây là ngoài việc bổ sung các dấu ngoặc kép này, các ký tự khác cũng đang được thay thế.
Rohit Verma

Việc hủy phiên bản chuỗi đó bằng cách sử dụng bộ tuần tự JSON sẽ xử lý cả dấu ngoặc kép và dấu gạch chéo thoát. Loại bỏ các dấu gạch chéo về phía trước của bạn bằng dấu gạch chéo ngược là điều mà một số trình tuần tự JSON làm - sử dụng trình giải mã sẽ biến \ / trở lại đơn giản / để bạn nhận được base-64 hợp lệ. Vì bạn đang nhận JSON, nên phân tích cú pháp JSON đó đúng cách luôn là một ý kiến ​​hay, ngay cả khi nó chỉ là một chuỗi đơn giản.
Joe Enos

3

Tôi đã sắp xếp một bối cảnh tương tự như bạn mô tả và tôi gặp phải lỗi tương tự. Tôi đã quản lý để làm cho nó hoạt động bằng cách xóa "từ đầu và cuối nội dung và thay thế \/bằng /.

Đây là đoạn mã:

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

Thay vào đó, bạn có thể cân nhắc sử dụng XML cho định dạng phản hồi:

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

Về phía khách hàng:

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
Mặc dù mã này có thể giải quyết được vấn đề, một câu trả lời tốt cũng nên giải thích những gì mã lệnh thực hiện và cách nó giúp.
BDL

2

Loại bỏ chuỗi không cần thiết thông qua Regex

Regex regex=new Regex(@"^[\w/\:.-]+;base64,");
base64File=regex.Replace(base64File,string.Empty);

1

Như Alex Filipovici đã đề cập, vấn đề là do mã hóa sai. Tệp tôi đã đọc UTF-8-BOMvà đã gặp lỗi ở trên Convert.FromBase64String(). Thay đổi thành UTF-8đã làm việc mà không có vấn đề.


1

Và đôi khi nó bắt đầu bằng dấu ngoặc kép, hầu hết các lần khi bạn gọi API từ dotNetCore 2 để lấy tệp

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

1
Không thể chuyển đổi từ chuỗi thành byte []
Urasquirrel

1

Có thể chuỗi sẽ giống như thế này data:image/jpeg;base64,/9j/4QN8RXh... Lần tách đầu tiên cho /và nhận mã thông báo thứ hai.

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

Sau đó Tách cho ;và lấy mã thông báo đầu tiên sẽ là định dạng. Trong trường hợp của tôi, đó là jpeg.

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

Sau đó, xóa dòng data:image/jpeg;base64,cho định dạng đã thu thập

CleanFaceData=Face.Replace($"data:image/{ImageFormat };base64,",string.Empty);
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.