L'input non è una stringa in base 64 valida poiché contiene un carattere non in base 64


98

Ho un servizio REST che legge un file e lo invia a un'altra applicazione console dopo averlo convertito in array Byte e quindi in stringa Base64. Questa parte funziona, ma quando lo stesso flusso viene ricevuto nell'applicazione, viene manipolato e non è più una stringa Base64 valida. Alcuni personaggi spazzatura vengono introdotti nel flusso.

L'eccezione ricevuta durante la riconversione del flusso in Byte è

L'input non è una stringa Base 64 valida poiché contiene un carattere non base 64, più di due caratteri di riempimento o uno spazio non vuoto tra i caratteri di riempimento

Al servizio:

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

All'applicazione:

       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
Probabilmente questo ha a che fare con Encoding.
Alex Filipovici

1
Sai quali "caratteri spazzatura" vengono inseriti?
Jim Mischel,

Il codice aggiornato è utile. Ora abbiamo bisogno di vedere la stringa che invii (cioè ssul servizio) e il contenuto che result.contenthai ricevuto (es . Non è necessario pubblicare l'intera stringa, solo fino al primo carattere alterato (o, se è ancora troppo lungo , alcune sottostringhe che mostrano cosa è stato inviato e cosa è stato ricevuto)
Jim Mischel

@JimMischel sì, ho notato che "/" viene sostituito con "\ /"
Rohit Verma

@RohitVerma Per la barra che viene sostituita, è nel contenuto HTML grezzo (te lo dirà Fiddler) o in result.Content? Questo ti dirà se il problema riguarda il server o il client.
Joe Enos,

Risposte:


94

Controlla se i dati dell'immagine contengono alcune informazioni di intestazione all'inizio:

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

Ciò causerà l'errore precedente.

Rimuovi tutto ciò che precede e include la prima virgola e sei a posto.

imageCode = "iVBORw0KGgoAAAANSUhEUgAAAMgAAABkC...

1
Ha avuto questo problema esatto in qualche modo. La logica è rimuovere tutto dopo che ,se data:è presente. Bam. Adesso sto lavorando.
Maxime Rouiller

var cleanerBase64 = imageCode.Substring (22); // rimuove i dati: image / png; base64
mejiamanuel57

3
Solo un po 'di codice per aiutare ... se (this.imageCode.Contains (', ')) this.imageCode = this.imageCode.Substring (this.imageCode.IndexOf (",") + 1, this.imageCode.Length - (this.imageCode.IndexOf (",") + 1));
Toby Simmerling

Io userei: .Split (',') [1]
Verthosa

1
str.Substring(str.LastIndexOf(',') + 1)dovrebbe farlo.
Alisson

65

Molto probabilmente viene convertito in un Base64 modificato, in cui i caratteri +e /vengono modificati in -e _. Vedi http://en.wikipedia.org/wiki/Base64#Implementations_and_history

In tal caso, è necessario modificarlo nuovamente:

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

1
Ho fatto questo .... Grazie a te !! Sostituendo i personaggi con quelli appropriati. Ma è questa una soluzione concreta? intendo dire come posso garantire che per tutti i file questo sarà il carattere da sostituire?
Rohit Verma,

2
@RohitVerma: non lo so. Devi scoprire dove vengono cambiati quei personaggi e determinare se è probabile che cambino altri personaggi. Non ho familiarità con RestSharp, quindi non posso offrire alcun consiglio. Se la mia risposta ha risposto alla tua domanda, è consuetudine contrassegnarla come risposta accettata. (Fare clic sul segno di spunta accanto alla risposta a sinistra.)
Jim Mischel

OMG Grazie! Questo e l'aggiunta dei caratteri "=" di riempimento necessari hanno risolto il mio problema. La funzione di decrittografia nell'API REST di Key Vault di Azure richiede questo processo e non lo documenta.
usato2può l'

33

Possiamo rimuovere l'input di stringa non necessario davanti al valore.

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

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

Questa soluzione ha funzionato per me. Ma questo è specifico per le immagini png. Esiste una sintassi generalizzata che sostituisca tutti i tipi di estensioni immagine?
Karan Desai

1
ho letto il tuo commento ora. non lo provo ma puoi usare questo: hdnImage.Replace ("data: image / png; base64,", String.Empty) .Replace ("data: image / jpg; base64,", String.Empty) .Replace ( "data: image / bmp; base64,", String.Empty); di nuovo, non lo provo. per favore prova a scrivere per me. cambierò.
Hasan Tuna Oruç

5

Nel caso in cui non conosci il tipo di immagine caricata e devi solo rimuovere la sua base64intestazione:

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

split e To List? usa piuttosto IndexOf e sottostringa
Emmanuel Gleizer

vedere demeranville.com/... e la questione è anche pubblicato qui: stackoverflow.com/questions/35388181/...
Emmanuel Gleizer

4

Poiché stai restituendo una stringa come JSON, quella stringa includerà le virgolette di apertura e chiusura nella risposta non elaborata. Quindi la tua risposta dovrebbe probabilmente essere:

"abc123XYZ=="

o qualsiasi altra cosa ... Puoi provare a confermarlo con Fiddler.

La mia ipotesi è che result.Contentsia la stringa grezza, comprese le virgolette. In tal caso, result.Contentsarà necessario deserializzare prima di poterlo utilizzare.


hai ragione, questo include "" ma il punto qui è che oltre all'aggiunta di queste virgolette vengono sostituiti anche altri caratteri.
Rohit Verma,

La deserializzazione di quella stringa utilizzando un serializzatore JSON si prenderà cura sia delle virgolette che della barra con escape. Evitare le barre in avanti con una barra rovesciata è qualcosa che fanno alcuni serializzatori JSON: l'uso di un deserializzatore trasformerà \ / di nuovo in semplice / in modo da ottenere una base 64 valida. Poiché stai ricevendo JSON, è sempre una buona idea analizzarlo correttamente, anche se è solo una semplice stringa.
Joe Enos,

3

Ho organizzato un contesto simile a quello che hai descritto e ho riscontrato lo stesso errore. Sono riuscito a farlo funzionare rimuovendo l' "inizio e la fine del contenuto e sostituendolo \/con /.

Ecco lo snippet di codice:

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

In alternativa, potresti prendere in considerazione l'utilizzo di XML per il formato della risposta:

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

Sul lato client:

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
Sebbene questo codice possa risolvere il problema, una buona risposta dovrebbe anche spiegare cosa fa il codice e come aiuta.
BDL

2

Rimuovere la stringa non necessaria tramite Regex

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

1

Come ha detto Alex Filipovici, il problema era una codifica sbagliata. Il file in cui ho letto era UTF-8-BOMe ho lanciato l'errore sopra Convert.FromBase64String(). Il passaggio a UTF-8ha funzionato senza problemi.


1

E alcune volte è iniziato con virgolette doppie, la maggior parte delle volte quando chiami API da dotNetCore 2 per ottenere il file

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

1
Impossibile convertire da stringa a byte []
Urasquirrel

1

Probabilmente la stringa sarebbe come questa data:image/jpeg;base64,/9j/4QN8RXh... Prima divisione per /e otterrebbe il secondo token.

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

Quindi Dividi ;e ottieni il primo token che sarà il formato. Nel mio caso è jpeg.

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

Quindi rimuovere la riga data:image/jpeg;base64,per il formato raccolto

CleanFaceData=Face.Replace($"data:image/{ImageFormat };base64,",string.Empty);
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.