इनपुट एक वैध आधार -64 स्ट्रिंग नहीं है क्योंकि इसमें गैर-आधार 64 वर्ण है


97

मेरे पास एक REST सेवा है जो एक फ़ाइल पढ़ती है और इसे बाइट सरणी में और उसके बाद बेस 64 स्ट्रिंग में परिवर्तित करने के बाद दूसरे कंसोल एप्लिकेशन पर भेजती है। यह हिस्सा काम करता है, लेकिन जब आवेदन पर एक ही स्ट्रीम प्राप्त होता है, तो यह हेरफेर हो जाता है और अब वैध बेस 64 स्ट्रिंग नहीं है। कुछ कबाड़ पात्रों को धारा में पेश किया जा रहा है।

बाइट को वापस धारा में परिवर्तित करते समय प्राप्त अपवाद है

इनपुट मान्य बेस -64 स्ट्रिंग नहीं है क्योंकि इसमें नॉन-बेस 64 कैरेक्टर, दो से अधिक पैडिंग कैरेक्टर या पैडिंग कैरेक्टर्स के बीच एक नॉन-व्हाइट स्पेस कैरेक्टर है।

सेवा में:

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

आवेदन पर:

       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
संभवत: इसी के साथ करना है Encoding
एलेक्स फिलीपोविसी

1
क्या आप जानते हैं कि "जंक कैरेक्टर" क्या डाले जा रहे हैं?
जिम मिसल

अद्यतन कोड उपयोगी है। अब हमें आपके द्वारा भेजे जाने वाले स्ट्रिंग (यानी sसेवा पर) और प्राप्त होने वाली सामग्री को देखने की आवश्यकता है (यानी result.content। आपको पूरे स्ट्रिंग को पोस्ट करने की आवश्यकता नहीं है, बस पहले मंगली चरित्र तक (या, यदि वह अभी भी बहुत लंबा है) , कुछ उपहास जो दिखाते हैं कि क्या भेजा गया था और क्या प्राप्त हुआ था)।
जिम मिसल

@JimMischel हाँ, मैंने देखा कि '/' को '\ /' से बदल दिया जा रहा है
रोहित वर्मा

@RohitVerma स्लैश को प्रतिस्थापित करने के लिए, यह है कि कच्चे HTML सामग्री में (फ़िडलर आपको बताएगा), या result.Content? यह आपको बताएगा कि समस्या सर्वर या क्लाइंट के साथ है।
जो एनोस

जवाबों:


92

जांचें कि क्या आपके छवि डेटा में शुरुआत में कुछ हेडर जानकारी शामिल हैं:

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

यह उपरोक्त त्रुटि का कारण होगा।

बस पहले कॉमा के साथ और उसके सामने सब कुछ हटा दें, और आप जाने के लिए अच्छा है।

imageCode = "iVBORw0KGgoAAAANSUhEUgAAAMgAAABkC...

किसी भी तरह यह सटीक मुद्दा था। तर्क सब कुछ को दूर करने के बाद है ,अगर data:मौजूद है। बैम। अभी व्यस्त हूँ।
मैक्सिम रूइलर

var CleanBase64 = imageCode.Substring (22); // डेटा को हटा दें: छवि / पीएनजी; बेस 64
मेजीमानुएल 57 एनडब्ल्यू

3
बस थोड़ा सा कोड मदद करने के लिए ...... अगर (यह .imageCode.Contains (',')) this.imageCode = this.imageCode.Substring (यह .imageCode.IndexOf (",") + 1, this.imageCode.Length - (यह .imageCode.IndexOf (",") + 1));
टॉबी सिमरलिंग

मैं उपयोग करूँगा: .Split (',') [1]
वर्थोसा

str.Substring(str.LastIndexOf(',') + 1)करना चाहिए।
एलिसन

64

बहुत संभवतः यह एक संशोधित बेस 64 में परिवर्तित हो रहा है, जहां +और /पात्रों को बदल दिया जाता है -और _Http://en.wikipedia.org/wiki/Base64#Implementations_and_history देखें

अगर ऐसा है, तो आपको इसे वापस बदलने की आवश्यकता है:

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

1
मैं यह कर दिया .... धन्यवाद! पात्रों को उपयुक्त लोगों के साथ बदलना। लेकिन क्या यह कोई ठोस उपाय है? मेरा मतलब है कि मैं कैसे गारंटी दे सकता हूं कि सभी फ़ाइलों के लिए यह चरित्र को बदलना होगा?
रोहित वर्मा

2
@ रोहितवर्मा: मुझे नहीं पता। आपको यह पता लगाना होगा कि उन पात्रों को कहां बदला जा रहा है, और यह निर्धारित करें कि क्या यह किसी अन्य वर्ण को बदलने की संभावना है। मैं RestSharp से परिचित नहीं हूं, इसलिए मैं वहां कोई सलाह नहीं दे सकता। यदि मेरी प्रतिक्रिया ने आपके प्रश्न का उत्तर दिया है, तो इसे स्वीकृत उत्तर के रूप में चिह्नित करने के लिए प्रथागत है। (बाईं ओर के उत्तर के बगल में स्थित चेकमार्क पर क्लिक करें।)
जिम मेंथेल

OMG धन्यवाद! यह और आवश्यक पैडिंग "=" वर्ण जोड़ने से मेरी समस्या हल हो गई। Azure के Key Vault REST API में डिक्रिप्ट फंक्शन को इस प्रक्रिया की आवश्यकता होती है और यह इसे प्रलेखित नहीं करता है।
used2could

33

हम मूल्य के सामने अनावश्यक स्ट्रिंग इनपुट को हटा सकते हैं।

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

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

इस समाधान ने मेरे लिए काम किया। लेकिन यह विशेष रूप से png छवियों के लिए है। क्या कोई सामान्यीकृत सिंटैक्स है जो सभी प्रकार के छवि एक्सटेंशन की जगह लेता है?
करण देसाई

1
अब मैं आपकी टिप्पणी पढ़ता हूं मैं यह कोशिश नहीं करता हूं, लेकिन आप इसका उपयोग कर सकते हैं: hdnImage.Replace ("डेटा: छवि / png, base64,", String.Empty) .Replace ("डेटा: छवि / jpg, base64,", String.Empty) .Replace ( "डेटा: छवि / बीएमपी; बेस 64,", स्ट्रिंग.इम्प्टी); फिर, मैं यह कोशिश नहीं करते। कृपया मेरे लिए प्रयास करें और लिखें। मैं बदलूँगा।
हसन टुना ओरुके

5

बस मामले में आप अपलोड की गई छवि के प्रकार को नहीं जानते हैं, और आपको बस इसे निकालने की आवश्यकता है base64 हेडर :

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

विभाजित और सूची के लिए? इंडेक्सऑफ और सबस्ट्रिंग का उपयोग करें
इमैनुएल ग्लीलाइज़र

demeranville.com/… देखें और प्रश्न भी यहाँ पोस्ट किया गया है: stackoverflow.com/questions/35388181/…
Emmanuel Gleizer

4

चूंकि आप JSON के रूप में एक स्ट्रिंग लौटा रहे हैं, उस स्ट्रिंग में कच्ची प्रतिक्रिया में उद्घाटन और समापन उद्धरण शामिल होंगे। तो आपकी प्रतिक्रिया संभवतः दिखनी चाहिए:

"abc123XYZ=="

या जो भी हो ... आप फ़िडलर के साथ इसकी पुष्टि करने की कोशिश कर सकते हैं।

मेरा अनुमान है कि result.Contentउद्धरण सहित कच्चे तार है। यदि ऐसा है, तो result.Contentइससे पहले कि आप इसका उपयोग कर सकते हैं, इसे deserialized करने की आवश्यकता होगी।


आप सही हैं, इसमें "" शामिल है, लेकिन यहां मुद्दा यह है कि इन उद्धरण चिह्नों के अलावा अन्य पात्रों को भी प्रतिस्थापित किया जा रहा है।
रोहित वर्मा

एक JSON सीरियलाइज़र का उपयोग करके उस स्ट्रिंग का वर्णन करना उद्धरण और बच गए स्लैश दोनों का ध्यान रखेगा। एक बैकस्लैश के साथ अपने फ़ॉरवर्ड स्लैश को बचाना कुछ ऐसा है जो JSON के कुछ सीरियलाइज़र्स करते हैं - एक डेज़राइज़र का उपयोग करते हुए \ सादे में बस वापस आ जाएगा / ताकि आपको वैध बेस -64 मिल जाए। जब से आप JSON प्राप्त कर रहे हैं, यह हमेशा JSON को ठीक से पार्स करने का एक अच्छा विचार है, भले ही यह सिर्फ एक साधारण स्ट्रिंग हो।
जो एनोस

3

मैंने आपके बताए अनुसार एक समान संदर्भ की व्यवस्था की और मैंने उसी त्रुटि का सामना किया। मैं इसे "सामग्री के आरंभ और अंत से हटाकर और इसके \/साथ प्रतिस्थापित करके काम करने में कामयाब रहा/

यहाँ कोड स्निपेट है:

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

विकल्प के रूप में, आप प्रतिक्रिया प्रारूप के लिए XML का उपयोग करने पर विचार कर सकते हैं:

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

ग्राहक पक्ष पर:

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
हालाँकि यह कोड समस्या को हल कर सकता है, एक अच्छे उत्तर को यह भी बताना चाहिए कि कोड क्या करता है और यह कैसे मदद करता है।
BDL

1

जैसा कि एलेक्स फिलीपोविसी ने उल्लेख किया था कि समस्या एक गलत एन्कोडिंग थी। मैंने जो फ़ाइल पढ़ी थी UTF-8-BOMउसमें उपरोक्त त्रुटि थी Convert.FromBase64String()UTF-8समस्याओं के बिना काम करने के लिए बदल रहा है।


1

और कुछ बार यह दोहरे उद्धरण चिह्नों के साथ शुरू हुआ, जब आप फ़ाइल प्राप्त करने के लिए डॉटनेटकोर 2 से एपीआई कॉल करते हैं

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

1
स्ट्रिंग से बाइट में परिवर्तित नहीं किया जा सकता है []
Urasquirrel

1

संभवतः स्ट्रिंग इस data:image/jpeg;base64,/9j/4QN8RXh... फर्स्ट के लिए विभाजित होगी /और दूसरा टोकन मिलेगा।

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

फिर विभाजित करें ;और पहले टोकन प्राप्त करें जो प्रारूप होगा। मेरे मामले में यह jpeg है।

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

फिर data:image/jpeg;base64,एकत्रित प्रारूप के लिए लाइन हटा दें

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

1

Regex के माध्यम से अनावश्यक स्ट्रिंग निकालें

Regex regex=new Regex(@"^[\w/\:.-]+;base64,");
base64File=regex.Replace(base64File,string.Empty);
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.