Die Eingabe ist keine gültige Base-64-Zeichenfolge, da sie ein Nicht-Base-64-Zeichen enthält


92

Ich habe einen REST-Dienst, der eine Datei liest und an eine andere Konsolenanwendung sendet, nachdem sie in ein Byte-Array und dann in eine Base64-Zeichenfolge konvertiert wurde. Dieser Teil funktioniert, aber wenn derselbe Stream in der Anwendung empfangen wird, wird er manipuliert und ist keine gültige Base64-Zeichenfolge mehr. Einige Junk-Charaktere werden in den Stream eingeführt.

Die Ausnahme, die beim Konvertieren des Streams zurück in Byte empfangen wird, ist

Die Eingabe ist keine gültige Base-64-Zeichenfolge, da sie ein Nicht-Base-64-Zeichen, mehr als zwei Füllzeichen oder ein nicht Leerzeichen unter den Füllzeichen enthält

Im Service:

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

Bei der Anwendung:

       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
Wahrscheinlich hat das damit zu tun Encoding.
Alex Filipovici

1
Wissen Sie, welche "Junk-Zeichen" eingefügt werden?
Jim Mischel

Der aktualisierte Code ist hilfreich. Jetzt müssen wir die Zeichenfolge sehen, die Sie senden (dh sim Dienst), und den Inhalt, der empfangen wird (dh result.contentSie müssen nicht die gesamte Zeichenfolge veröffentlichen, sondern nur bis zum ersten verstümmelten Zeichen (oder, wenn das noch zu lang ist) , einige Teilzeichenfolgen, die zeigen, was gesendet und was empfangen wurde)
Jim Mischel

@ JimMischel Ja, ich habe bemerkt, dass '/' durch '\ /' ersetzt wird
Rohit Verma

@RohitVerma Wenn der Schrägstrich ersetzt wird, ist das in den rohen HTML-Inhalten (Fiddler wird es Ihnen sagen) oder in result.Content? Hier erfahren Sie, ob das Problem beim Server oder beim Client liegt.
Joe Enos

Antworten:


83

Überprüfen Sie, ob Ihre Bilddaten zu Beginn einige Header-Informationen enthalten:

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

Dies führt zu dem oben genannten Fehler.

Entfernen Sie einfach alles vor und einschließlich des ersten Kommas, und schon kann es losgehen.

imageCode = "iVBORw0KGgoAAAANSUhEUgAAAMgAAABkC...

Hatte genau dieses Problem irgendwie. Die Logik ist alles zu entfernen , nachdem ,wenn data:vorhanden ist. Bam. Arbeite jetzt.
Maxime Rouiller

var CleanerBase64 = imageCode.Substring (22); // Daten entfernen: image / png; base64
mejiamanuel57

3
Nur ein bisschen Code, um zu helfen ...... if (this.imageCode.Contains (',')) this.imageCode = this.imageCode.Substring (this.imageCode.IndexOf (",") + 1, this.imageCode.Length - (this.imageCode.IndexOf (",") + 1));
Toby Simmerling

Ich würde verwenden: .Split (',') [1]
Verthosa

str.Substring(str.LastIndexOf(',') + 1)Sollte es tun.
Alisson

63

Sehr wahrscheinlich wird es zu einem modifizierten Base64 umgewandelt zu werden , wo die +und /Zeichen geändert werden -und _. Siehe http://en.wikipedia.org/wiki/Base64#Implementations_and_history

Wenn dies der Fall ist, müssen Sie es zurück ändern:

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

1
Ich habe das geschafft ... Danke an dich !! Ersetzen Sie die Zeichen durch die entsprechenden. Aber ist das eine konkrete Lösung? Ich meine, wie kann ich garantieren, dass für alle Dateien dies das Zeichen ist, das ersetzt werden soll?
Rohit Verma

2
@RohitVerma: Ich weiß es nicht. Sie müssen herausfinden, wo diese Zeichen geändert werden, und feststellen, ob wahrscheinlich andere Zeichen geändert werden. Ich bin mit RestSharp nicht vertraut, daher kann ich dort keine Ratschläge geben. Wenn meine Antwort Ihre Frage beantwortet hat, ist es üblich, sie als akzeptierte Antwort zu markieren. (Klicken Sie auf das Häkchen neben der Antwort auf der linken Seite.)
Jim Mischel

OMG Danke! Dies und das Hinzufügen der erforderlichen Auffüllzeichen "=" lösten mein Problem. Die Entschlüsselungsfunktion in der Key Vault-REST-API von Azure benötigt diesen Prozess und dokumentiert ihn nicht.
used2could

30

Wir können unnötige Zeichenfolgeneingaben vor dem Wert entfernen.

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

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

Diese Lösung hat bei mir funktioniert. Dies ist jedoch speziell für PNG-Bilder. Gibt es eine verallgemeinerte Syntax, die alle Arten von Bilderweiterungen ersetzt?
Karan Desai

1
Ich habe deinen Kommentar jetzt gelesen. Ich versuche dies nicht, aber Sie können dies verwenden: hdnImage.Replace ("Daten: image / png; base64,", String.Empty) .Replace ("Daten: image / jpg; base64,", String.Empty) .Replace ( "data: image / bmp; base64", String.Empty); wieder versuche ich das nicht. Bitte versuchen Sie, für mich zu schreiben. Ich werde mich verändern.
Hasan Thunfisch Oruç

5

Nur für den Fall, dass Sie den Typ des hochgeladenen Bildes nicht kennen und nur dessen base64Kopfzeile entfernen müssen :

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

teilen und auflisten? Verwenden Sie lieber IndexOf und Teilzeichenfolge
Emmanuel Gleizer


4

Da Sie eine Zeichenfolge als JSON zurückgeben, enthält diese Zeichenfolge die öffnenden und schließenden Anführungszeichen in der Rohantwort. Ihre Antwort sollte also wahrscheinlich so aussehen:

"abc123XYZ=="

oder was auch immer ... Sie können versuchen, dies mit Fiddler zu bestätigen.

Ich vermute, dass dies die Rohzeichenfolge ist result.Content, einschließlich der Anführungszeichen. Wenn dies der Fall ist, result.Contentmuss es deserialisiert werden, bevor Sie es verwenden können.


Sie haben Recht, dies schließt "" ein, aber der Punkt hier ist, dass neben dem Hinzufügen dieser Anführungszeichen auch andere Zeichen ersetzt werden.
Rohit Verma

Durch Deserialisieren dieser Zeichenfolge mit einem JSON-Serializer werden sowohl die Anführungszeichen als auch der maskierte Schrägstrich berücksichtigt. Es ist etwas, was einige JSON-Serializer tun, wenn Sie Ihre Schrägstriche mit einem Backslash umgehen. Wenn Sie einen Deserializer verwenden, wird \ / back einfach /, sodass Sie eine gültige Basis-64 erhalten. Da Sie JSON erhalten, ist es immer eine gute Idee, JSON richtig zu analysieren, auch wenn es sich nur um eine einfache Zeichenfolge handelt.
Joe Enos

3

Ich habe einen ähnlichen Kontext wie Sie beschrieben und den gleichen Fehler festgestellt. Ich schaffte es zum Laufen zu bringen , indem die Entfernung "von dem Anfang und das Ende des Inhalts und durch den Ersatz \/mit /.

Hier ist das Code-Snippet:

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

Alternativ können Sie XML für das Antwortformat verwenden:

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

Auf der Client-Seite:

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);

6
Obwohl dieser Code das Problem lösen könnte, sollte eine gute Antwort auch erklären, was der Code tut und wie er hilft.
BDL

1

Wie Alex Filipovici erwähnte, war das Problem eine falsche Codierung. Die Datei, die ich eingelesen habe, war UTF-8-BOMund warf den obigen Fehler auf Convert.FromBase64String(). Der Wechsel zu UTF-8hat ohne Probleme funktioniert.


1

Und manchmal begann es mit doppelten Anführungszeichen, meistens, wenn Sie die API von dotNetCore 2 aus aufrufen, um eine Datei abzurufen

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

1
Kann nicht von Zeichenfolge zu Byte konvertieren []
Urasquirrel
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.