Input bukan string Base-64 yang valid karena berisi karakter non-base 64

98

Saya memiliki layanan REST yang membaca file dan mengirimkannya ke aplikasi konsol lain setelah mengubahnya menjadi array Byte dan kemudian ke string Base64. Bagian ini berfungsi, tetapi ketika aliran yang sama diterima di aplikasi, itu akan dimanipulasi dan tidak lagi menjadi string Base64 yang valid. Beberapa karakter sampah diperkenalkan ke arus.

Pengecualian yang diterima saat mengubah aliran kembali ke Byte adalah

Input bukan string Base-64 yang valid karena berisi karakter non-base 64, lebih dari dua karakter padding, atau karakter non-spasi kosong di antara karakter padding

Di Layanan:

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

Di Aplikasi:

       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); 
Rohit Verma
sumber
4
Mungkin ini ada hubungannya dengan Encoding.
Alex Filipovici
1
Apakah Anda tahu "karakter sampah" apa yang dimasukkan?
Jim Mischel
Kode yang diperbarui sangat membantu. Sekarang kita perlu melihat string yang Anda kirim (yaitu spada layanan) dan konten yang diterima (yaitu result.content. Anda tidak perlu memposting seluruh string, cukup hingga karakter pertama yang rusak (atau, jika itu masih terlalu panjang , beberapa substring yang menunjukkan apa yang dikirim dan apa yang diterima).
Jim Mischel
@JimMischel ya, saya perhatikan bahwa '/' diganti dengan '\ /'
Rohit Verma
@RohitVerma Agar garis miring diganti, apakah itu dalam konten HTML mentah (Fiddler akan memberi tahu Anda), atau di result.Content? Itu akan memberi tahu Anda jika masalahnya ada pada server atau klien.
Joe Enos

Jawaban:

95

Periksa apakah data gambar Anda berisi beberapa informasi header di awal:

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

Ini akan menyebabkan kesalahan di atas.

Hapus saja semua yang ada di depan dan termasuk koma pertama, dan Anda siap melakukannya.

imageCode = "iVBORw0KGgoAAAANSUhEUgAAAMgAAABkC...
bendecko
sumber
1
Entah bagaimana, memiliki masalah yang tepat ini. Logikanya adalah menghapus semuanya setelah ,jika data:ada. Bam. Bekerja sekarang.
Maxime Rouiller
var cleanerBase64 = imageCode.Substring (22); // hapus data: image / png; base64
mejiamanuel57
3
Hanya sedikit kode untuk membantu ...... if (this.imageCode.Contains (',')) this.imageCode = this.imageCode.Substring (this.imageCode.IndexOf (",") + 1, this.imageCode.Length - (this.imageCode.IndexOf (",") + 1));
Toby Simmerling
Saya akan menggunakan: .Split (',') [1]
Verthosa
1
str.Substring(str.LastIndexOf(',') + 1)harus melakukannya.
Alisson
65

Sangat mungkin itu diubah menjadi Base64 yang dimodifikasi, di mana karakter +dan /diubah menjadi -dan _. Lihat http://en.wikipedia.org/wiki/Base64#Implementations_and_history

Jika demikian, Anda perlu mengubahnya kembali:

string converted = base64String.Replace('-', '+');
converted = converted.Replace('_', '/');
Jim Mischel
sumber
1
Aku menyelesaikan ini .... Terima kasih !! Mengganti karakter dengan yang sesuai. Tetapi apakah ini solusi yang konkret? Maksud saya, bagaimana saya bisa menjamin bahwa untuk semua file ini akan menjadi karakter yang akan diganti?
Rohit Verma
2
@RohitVerma: Saya tidak tahu. Anda perlu mencari tahu di mana karakter-karakter tersebut diubah, dan menentukan apakah kemungkinan akan mengubah karakter lain. Saya tidak terbiasa dengan RestSharp, jadi saya tidak bisa menawarkan saran apa pun di sana. Jika jawaban saya menjawab pertanyaan Anda, biasanya menandainya sebagai jawaban yang diterima. (Klik tanda centang di sebelah jawaban di sebelah kiri.)
Jim Mischel
OMG Terima kasih! Ini dan menambahkan karakter "=" padding yang diperlukan memecahkan masalah saya. Fungsi dekripsi di REST API Vault Kunci Azure memerlukan proses ini dan tidak mendokumentasikannya.
used2could
33

Kami dapat menghapus input string yang tidak perlu di depan nilai.

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

byte[] image64 = Convert.FromBase64String(convert);
Hasan Tuna Oruç
sumber
Solusi ini berhasil untuk saya. Tapi ini khusus untuk gambar png. Apakah ada sintaks umum yang menggantikan semua jenis ekstensi gambar?
Karan Desai
1
saya membaca komentar Anda sekarang. saya tidak mencoba ini tetapi Anda dapat menggunakan ini: hdnImage.Replace ("data: image / png; base64,", String.Empty) .Replace ("data: image / jpg; base64,", String.Empty) .Replace ( "data: image / bmp; base64,", String.Empty); sekali lagi, saya tidak mencoba ini. silakan coba dan tulis untuk saya. Saya akan berubah.
Hasan Tuna Oruç
5

Untuk berjaga-jaga jika Anda tidak tahu jenis gambar yang diunggah, dan Anda hanya perlu menghapus base64headernya:

 var imageParts = model.ImageAsString.Split(',').ToList<string>();
 //Exclude the header from base64 by taking second element in List.
 byte[] Image = Convert.FromBase64String(imageParts[1]);
Mahdi Alkhatib
sumber
split dan To List? lebih baik menggunakan IndexOf dan substring
Emmanuel Gleizer
lihat demeranville.com/… dan pertanyaannya juga diposting di sini: stackoverflow.com/questions/35388181/…
Emmanuel Gleizer
4

Karena Anda mengembalikan string sebagai JSON, string itu akan menyertakan tanda kutip pembuka dan penutup dalam respons mentah. Jadi tanggapan Anda mungkin akan terlihat seperti:

"abc123XYZ=="

atau apa pun ... Anda dapat mencoba mengonfirmasi ini dengan Fiddler.

Dugaan saya adalah bahwa result.Contentstring mentah, termasuk tanda kutip. Jika demikian, maka result.Contentperlu dilakukan deserialisasi sebelum Anda dapat menggunakannya.

Joe Enos
sumber
Anda benar, ini termasuk "" tetapi intinya di sini adalah bahwa selain penambahan tanda kutip ini, karakter lain juga diganti.
Rohit Verma
Deserialisasi string itu menggunakan serializer JSON akan menangani tanda kutip dan garis miring yang lolos. Melarikan diri dari garis miring ke depan dengan garis miring terbalik adalah sesuatu yang dilakukan beberapa pembuat serial JSON - menggunakan deserializer akan mengubah \ / kembali menjadi polos / sehingga Anda akan mendapatkan basis 64 yang valid. Karena Anda menerima JSON, sebaiknya parse JSON tersebut dengan benar, meskipun itu hanya string sederhana.
Joe Enos
3

Saya mengatur konteks yang sama seperti yang Anda jelaskan dan saya menghadapi kesalahan yang sama. Saya berhasil membuatnya berfungsi dengan menghapus "dari awal dan akhir konten dan dengan menggantinya \/dengan/ .

Berikut adalah cuplikan kodenya:

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

Sebagai alternatif, Anda mungkin mempertimbangkan menggunakan XML untuk format respons:

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

Di sisi klien:

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);
Alex Filipovici
sumber
3
var spl = item.Split('/')[1];
var format =spl.Split(';')[0];           
stringconvert=item.Replace($"data:image/{format};base64,",String.Empty);
mostafa kazemi
sumber
7
Meskipun kode ini dapat menyelesaikan masalah, jawaban yang baik juga harus menjelaskan apa yang dilakukan kode tersebut dan bagaimana hal itu membantu.
BDL
2

Hapus string yang tidak perlu melalui Regex

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

Seperti yang dikatakan Alex Filipovici , masalahnya adalah pengkodean yang salah. File yang saya baca adalah UTF-8-BOMdan menampilkan kesalahan di atas Convert.FromBase64String(). Mengubah menjadi UTF-8berhasil tanpa masalah.

pengujian
sumber
1

Dan beberapa kali itu dimulai dengan tanda kutip ganda, sebagian besar saat Anda memanggil API dari dotNetCore 2 untuk mendapatkan file

string string64 = string64.Replace(@"""", string.Empty);
byte[] bytes = Convert.ToBase64String(string64);
pengguna193679
sumber
1
Tak dapat mengonversi dari string ke byte []
Urasquirrel
1

Mungkin stringnya akan seperti ini data:image/jpeg;base64,/9j/4QN8RXh... First split /dan dapatkan token kedua.

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

Kemudian Pisahkan ;dan dapatkan token pertama yang akan menjadi formatnya. Dalam kasus saya, ini adalah jpeg.

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

Kemudian hapus baris data:image/jpeg;base64,untuk format yang dikumpulkan

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