Girdi, 64 tabanlı olmayan bir karakter içerdiğinden geçerli bir Base-64 dizesi değil


100

Bir dosyayı okuyan ve onu Byte dizisine ve ardından Base64 dizesine dönüştürdükten sonra başka bir konsol uygulamasına gönderen bir REST hizmetim var. Bu parça çalışır, ancak uygulamada aynı akış alındığında, manipüle edilir ve artık geçerli bir Base64 dizesi değildir. Bazı önemsiz karakterler akışa giriyor.

Akışı Bayte geri dönüştürürken alınan istisna

Giriş, 64 tabanlı olmayan bir karakter, ikiden fazla dolgu karakteri veya dolgu karakterleri arasında beyaz olmayan boşluk karakteri içerdiğinden geçerli bir Base-64 dizesi değildir

Serviste:

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

Başvuruda:

       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
Muhtemelen bununla ilgisi var Encoding.
Alex Filipovici

1
Hangi "gereksiz karakterlerin" eklendiğini biliyor musunuz?
Jim Mischel

Güncellenen kod faydalıdır. Şimdi gönderdiğiniz dizeyi (yani shizmette) ve alınan içeriği görmemiz gerekiyor (yani , result.contentdizenin tamamını, yalnızca ilk karıştırılan karaktere kadar (veya bu hala çok uzunsa) göndermenize gerek yok , neyin gönderildiğini ve alındığını gösteren bazı alt
dizeler

Evet @JimMischel i '/' '\ /' ile değiştirilir oluyor fark
Rohit Verma

@RohitVerma Eğik çizgi değiştirilmek için, bu ham HTML içeriğinde mi (Fiddler size söyleyecektir) result.Contentmı yoksa içinde mi? Bu, sorunun sunucuda mı yoksa istemcide mi olduğunu size söyleyecektir.
Joe Enos

Yanıtlar:


96

Görüntü verilerinizin başında bazı başlık bilgileri içerip içermediğini kontrol edin:

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

Bu, yukarıdaki hataya neden olacaktır.

Sadece önündeki ve ilk virgül dahil her şeyi kaldırın ve gitmeniz iyi olur.

imageCode = "iVBORw0KGgoAAAANSUhEUgAAAMgAAABkC...

1
Bir şekilde bu kesin sorunu yaşadım Mantık, ,eğer data:mevcutsa sonra her şeyi kaldırmaktır . Bam. Şimdi çalışıyor.
Maxime Rouiller

var cleanerBase64 = imageCode.Substring (22); // verileri kaldır: image / png; base64
mejiamanuel57

3
Yardımcı olmak için biraz kod ...... if (this.imageCode.Contains (',')) this.imageCode = this.imageCode.Substring (this.imageCode.IndexOf (",") + 1, this.imageCode.Length - (this.imageCode.IndexOf (",") + 1));
Toby Simmerling

Şunu kullanırdım: .Split (',') [1]
Verthosa

1
str.Substring(str.LastIndexOf(',') + 1)yapmalı.
Alisson

65

Çok olasılıkla değiştirilmiş Base64, dönüştürülen vurmayacak +ve /karakterler değiştirilir -ve _. Bkz http://en.wikipedia.org/wiki/Base64#Implementations_and_history

Eğer durum buysa, tekrar değiştirmeniz gerekir:

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

1
Bunu hallettim .... Sayende !! Karakterleri uygun olanlarla değiştirmek. Ancak bu somut bir çözüm mü? Demek istediğim, tüm dosyalar için bunun değiştirilecek karakter olacağını nasıl garanti edebilirim?
Rohit Verma

2
@RohitVerma: Bilmiyorum. Bu karakterlerin nerede değiştiğini bulmanız ve diğer karakterleri değiştirme olasılığının olup olmadığını belirlemeniz gerekir. RestSharp'a aşina olmadığım için orada herhangi bir tavsiye veremem. Cevabım sorunuzu cevapladıysa, onu kabul edilen cevap olarak işaretlemek gelenekseldir. (Soldaki cevabın yanındaki onay işaretine tıklayın.)
Jim Mischel

OMG Teşekkürler! Bu ve gerekli dolgu "=" karakterlerini eklemek sorunumu çözdü. Azure'un Key Vault REST API'sindeki şifre çözme işlevi bu işleme ihtiyaç duyar ve bunu belgelemez.
used2

33

Değerin önüne gereksiz string girişini kaldırabiliriz.

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

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

Bu çözüm benim için çalıştı. Ancak bu özellikle png resimleri içindir. Her türlü görüntü uzantısının yerini alan genelleştirilmiş bir sözdizimi var mı?
Karan Desai

1
Şimdi yorumunu okudum. bunu denemiyorum ama şunu kullanabilirsiniz: hdnImage.Replace ("data: image / png; base64,", String.Empty) .Replace ("data: image / jpg; base64,", String.Empty) .Değiştir ( "veri: resim / bmp; base64,", String.Empty); Yine, bunu denemiyorum. lütfen benim için yazmayı dene. değişeceğim.
Hasan Tuna Oruç

5

Sadece yüklenen görüntünün türünü bilmiyorsanız ve sadece base64başlığını kaldırmanız gerekir :

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

bölünmüş ve Listelenecek mi? kullanmak yerine IndexOf ve alt dize
Emmanuel Gleizer


4

Bir dizeyi JSON olarak döndürdüğünüz için, bu dize ham yanıtta açılış ve kapanış tırnak işaretlerini içerecektir. Yani cevabınız muhtemelen şöyle görünmelidir:

"abc123XYZ=="

ya da her neyse ... Bunu Fiddler ile onaylamayı deneyebilirsiniz.

Tahminimce, result.Contenttırnaklar dahil ham dizge. Durum buysa, result.Contentkullanmadan önce seri durumunun kaldırılması gerekecektir.


haklısınız, buna "" dahildir, ancak buradaki nokta, bu tırnak işaretlerinin yanı sıra diğer karakterlerin de değiştirilmesidir.
Rohit Verma

Bir JSON serileştirici kullanarak bu dizenin serisini kaldırmak, hem tırnak işaretlerini hem de çıkış karakterli eğik çizgiyi halleder. Ters eğik çizgiyle öne eğik çizgilerinizden kaçmak, bazı JSON serileştiricilerin yaptığı bir şeydir - bir seriyi kaldırıcı kullanmak \ / geri yalnızca düz / böylece geçerli taban 64 elde edersiniz. JSON aldığınız için, bu JSON'u basit bir dize olsa bile doğru şekilde ayrıştırmak her zaman iyi bir fikirdir.
Joe Enos

3

Sizin tarif ettiğiniz gibi benzer bir bağlam düzenledim ve aynı hatayla karşılaştım. Ben kaldırarak çalışma başardı "başında ve içeriğin ucundan ve değiştirerek \/ile /.

İşte kod pasajı:

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

Alternatif olarak, yanıt biçimi için XML kullanmayı düşünebilirsiniz:

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

Müşteri tarafında:

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
Bu kod sorunu çözse de, iyi bir yanıt , kodun ne yaptığını ve nasıl yardımcı olduğunu da açıklamalıdır .
BDL

2

Regex aracılığıyla gereksiz dizeyi kaldırın

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

1

As Alex Filipovici dile getirilen konu yanlış kodlama oldu. Okuduğum dosya UTF-8-BOM, yukarıdaki hatayı attı Convert.FromBase64String(). Sorunsuz UTF-8çalışmak için değiştirmek .


1

Ve bazen çift tırnakla başladı, çoğu zaman dosya almak için dotNetCore 2'den API çağırdığınızda

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

1

1

Muhtemelen dize şöyle olacaktır: data:image/jpeg;base64,/9j/4QN8RXh... İlk ayırma /ve ikinci jetonu alma.

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

Daha sonra Bölün ;ve format olacak ilk jetonu alın. Benim durumumda jpeg.

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

Ardından data:image/jpeg;base64,toplanan biçim için satırı kaldırın

CleanFaceData=Face.Replace($"data:image/{ImageFormat };base64,",string.Empty);
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.