Given this simple class:
class HasBytes
{
public byte[] Bytes { get; set; }
}
I can put it through JSON.NET such that the byte array is base-64 encoded:
var bytes = new HasBytes { Bytes = new byte[] { 1, 2, 3, 4 } };
var json = JsonConvert.SerializeObject(bytes);
Then I can read it back again in this slightly over-complicated way:
TextReader textReader = new StringReader(json);
JsonReader jsonReader = new JsonTextReader(textReader);
var result = (HasBytes)JsonSerializer.Create(null)
.Deserialize(jsonReader, typeof(HasBytes));
All good. But if I first turn the contents of jsonReader into a JToken:
var jToken = JToken.ReadFrom(jsonReader);
And then turn that back into a JsonReader by wrapping it in a JTokenReader:
jsonReader = new JTokenReader(jToken);
Then the deserialization throws an exception: "Expected bytes but got string".
Shouldn't the new JsonReader be logically equivalent to the original one? Why does the "raw" JsonTextReader have the ability to treat a string as a base-64 byte array whereas the JTokenReader version does not?
This appears to be a bug in JTokenReader as far as I can see, so I've reported it here.
Update: fixed in JSON.NET 3.5 release 7.
Related
can you help me with refactoring this method from java to kotlin, please ? I have a problem with ByteBuffer in return statement. Looks like in Kotlin it doesnt work that way.
public String encryptData(Object payload, Key secretKey)
throws NoSuchAlgorithmException, NoSuchPaddingException, JsonProcessingException, BadPaddingException,
IllegalBlockSizeException, InvalidAlgorithmParameterException, InvalidKeyException {
var initialVector = new byte[INITIAL_VECTOR_SIZE];
secureRandom.nextBytes(initialVector);
var cipher = Cipher.getInstance(AES_TRANSFORMATION);
cipher.init(Cipher.ENCRYPT_MODE, secretKey, new IvParameterSpec(initialVector));
var data = cipher.doFinal(objectMapper.writeValueAsString(payload).getBytes());
var byteBuffer = ByteBuffer.allocate(initialVector.length + data.length);
return new String(
Base64.getEncoder()
.encode(byteBuffer
.put(0, initialVector)
.put(INITIAL_VECTOR_SIZE, data))
.array());
}
It's cleaner to setup your byteBuffer outside of base 64 conversion. Once you have done that, you can:
...
return Base64.getEncoder().encodeToString(byteBuffer)
Occasionally getting "Unauthorized Error" when my Base64 encoded token contains a "+" sign (which is a valid Base 64 character)
I am using Visualize-JS to render the Jasper report in MVC Boilerplate. To authenticate every request, I am using the pre authorization flow where I am sending a Base64 encoded token from my application and on Jasper server decoding it.
Everything is working fine except, occasionally I am getting "Unauthorized Error". When I checked I found it is only failing when my Base64 encoded token contains a "+" sign (which is a valid Base 64 character). My C# code is URL encoding the + sign as %2B whereas the Java code while decoding the same URL converts %2B into a space. (Note - I am encoding in C# and decoding in Java since, Jasper server only supports JAR files).
Is anyone else facing this or have faced earlier and found the solution?
For now, as a work around I am replacing the space with a + sign but, I am searching for a better solution.
Here is the faulty token, C# code for encoding and Java code for decoding
Token - f0NNFeJKfvBiWZP7I7vTGHb8yhiDEmkoE35p6ueQceBiMUJbPoaF927UsHn7w2AdCbKmfjjfZyKxm8iwrTo37kLZPE91EuT4WJrQ/KjQ+r0=
C# Code for Encryption -
public string Encrypt(string plainText)
{
byte[] plainBytes = Encoding.UTF8.GetBytes(plainText);
return HttpUtility.UrlEncode(Convert.ToBase64String(Encrypt(plainBytes, GetRijndaelManaged(_config.EncryptionKey))));
}
public RijndaelManaged GetRijndaelManaged(string secretKey)
{
byte[] keyBytes = new byte[16];
byte[] secretKeyBytes = Encoding.UTF8.GetBytes(secretKey);
Array.Copy(secretKeyBytes, keyBytes, Math.Min(keyBytes.Length, secretKeyBytes.Length));
return new RijndaelManaged
{
Mode = CipherMode.CBC,
Padding = PaddingMode.PKCS7,
KeySize = 128,
BlockSize = 128,
Key = keyBytes,
IV = keyBytes
};
}
public byte[] Encrypt(byte[] plainBytes, RijndaelManaged rijndaelManaged)
{
return rijndaelManaged.CreateEncryptor().TransformFinalBlock(plainBytes, 0, plainBytes.Length);
}
Java Code - encryptedText here is the token mentioned above
public String decrypt(String encryptedText){
encryptedText = decode(encryptedText);
byte[] cipheredBytes = Base64.getDecoder().decode(encryptedText);
byte[] keyBytes = getKeyBytes(secretKey);
return new String(decrypt(cipheredBytes, keyBytes, keyBytes), "UTF-8");
}
public static String decode(String url)
{
try {
String prevURL="";
String decodeURL=url;
while(!prevURL.equals(decodeURL))
{
prevURL=decodeURL;
decodeURL=URLDecoder.decode( decodeURL, "UTF-8" );
}
return decodeURL.replace(" ", "+");
} catch (UnsupportedEncodingException e) {
return "Issue while decoding" +e.getMessage();
}
}
private byte[] getKeyBytes(String key) throws UnsupportedEncodingException{
byte[] keyBytes= new byte[16];
byte[] parameterKeyBytes= key.getBytes("UTF-8");
System.arraycopy(parameterKeyBytes, 0, keyBytes, 0, Math.min(parameterKeyBytes.length, keyBytes.length));
return keyBytes;
}
I am using MVC4. My requirement is:
I have to convert the file into byte array and save to database varbinary column.
For this I written code like below:
public byte[] Doc { get; set; }
Document.Doc = GetFilesBytes(PostedFile);
public static byte[] GetFilesBytes(HttpPostedFileBase file)
{
MemoryStream target = new MemoryStream();
file.InputStream.CopyTo(target);
return target.ToArray();
}
I am downloading the file by using the following code:
public ActionResult Download(int id)
{
List<Document> Documents = new List<Document>();
using (SchedulingServiceInstanceManager facade = new SchedulingServiceInstanceManager("SchedulingServiceWsHttpEndPoint"))
{
Document Document = new Document();
Document.DMLType = Constant.DMLTYPE_SELECT;
Documents = facade.GetDocuments(Document);
}
var file = Documents.FirstOrDefault(f => f.DocumentID == id);
return File(file.Doc.ToArray(), "application/octet-stream", file.Name);
}
when I am downloading pdf file then it is showing message as "There was an error opening this document. The file is damaged and could not be repaired."
Any thing else I need to do?
I tried with the following code but no luck
return File(file.Doc.ToArray(), "application/pdf", file.Name);
Please help me to solve the issue.
Thanks in advance.
Please try as in below code in your controller
FileStream stream = File.OpenRead(#"c:\path\to\your\file\here.txt");
byte[] fileBytes= new byte[stream.Length];
stream.Read(fileBytes, 0, fileBytes.Length);
stream.Close();
//Begins the process of writing the byte array back to a file
using (Stream file = File.OpenWrite(#"c:\path\to\your\file\here.txt"))
{
file.Write(fileBytes, 0, fileBytes.Length);
}
It may helps you...
Does the IsolatedStorageSettings.Save method in a Windows Phone application save the whole dictionary regardless of the changes we made in it? I.e. if we have say 50 items in it, and change just one, does the Save method saves (serializes, etc) the whole dictionary again and again? Is there any detailed documentation on this class and does anybody know what data storage format is used "under the hood"?
I've managed to find the implementation of the IsolatedStorageSettings.Save method in the entrails of the Windows Phone emulator VHD images supplied with the Windows Phone SDK (the answer to this question on SO helped me to do that). Here is the source code of the method:
public void Save()
{
lock (this.m_lock)
{
using (IsolatedStorageFileStream isolatedStorageFileStream = this._appStore.OpenFile(this.LocalSettingsPath, 4))
{
using (MemoryStream memoryStream = new MemoryStream())
{
Dictionary<Type, bool> dictionary = new Dictionary<Type, bool>();
StringBuilder stringBuilder = new StringBuilder();
using (Dictionary<string, object>.ValueCollection.Enumerator enumerator = this._settings.get_Values().GetEnumerator())
{
while (enumerator.MoveNext())
{
object current = enumerator.get_Current();
if (current != null)
{
Type type = current.GetType();
if (!type.get_IsPrimitive() && type != typeof(string))
{
dictionary.set_Item(type, true);
if (stringBuilder.get_Length() > 0)
{
stringBuilder.Append('\0');
}
stringBuilder.Append(type.get_AssemblyQualifiedName());
}
}
}
}
stringBuilder.Append(Environment.get_NewLine());
byte[] bytes = Encoding.get_UTF8().GetBytes(stringBuilder.ToString());
memoryStream.Write(bytes, 0, bytes.Length);
DataContractSerializer dataContractSerializer = new DataContractSerializer(typeof(Dictionary<string, object>), dictionary.get_Keys());
dataContractSerializer.WriteObject(memoryStream, this._settings);
if (memoryStream.get_Length() > this._appStore.get_AvailableFreeSpace() + isolatedStorageFileStream.get_Length())
{
throw new IsolatedStorageException(Resx.GetString("IsolatedStorageSettings_NotEnoughSpace"));
}
isolatedStorageFileStream.SetLength(0L);
byte[] array = memoryStream.ToArray();
isolatedStorageFileStream.Write(array, 0, array.Length);
}
}
}
}
So, as we can see the whole dictionary is serialized every time when we call Save. And we can see from code what method is used to serialize the collection values.
Can anyone please tell me how an image(.jpg,.gif,.bmp) is converted into a byte array ?
The easiest way to convert an image to bytes is to use the ImageConverter class under the System.Drawing namespace
public static byte[] ImageToByte(Image img)
{
ImageConverter converter = new ImageConverter();
return (byte[])converter.ConvertTo(img, typeof(byte[]));
}
I've assumed what you want is the pixel values. Assuming bitmap is a System.Windows.Media.Imaging.BitmapSource:
int stride = bitmap.PixelWidth * ((bitmap.Format.BitsPerPixel + 7) / 8);
byte[] bmpPixels = new byte[bitmap.PixelHeight * stride];
bitmap.CopyPixels(bmpPixels, stride, 0);
Note that the 'stride' is the number of bytes required for each row of pixel ddata. Some more explanation available here.
If your image is already in the form of a System.Drawing.Image, then you can do something like this:
public byte[] convertImageToByteArray(System.Drawing.Image image)
{
using (MemoryStream ms = new MemoryStream())
{
image.Save(ms, System.Drawing.Imaging.ImageFormat.Gif);
// or whatever output format you like
return ms.ToArray();
}
}
You would use this function with the image in your picture box control like this:
byte[] imageBytes = convertImageToByteArray(pictureBox1.Image);
to get the bytes from any file try:
byte[] bytes = File.ReadAllBytes(pathToFile);
Based off of MusiGenesis; helped me a lot but I had many image types. This will save any image type that it can read.
System.Drawing.Imaging.ImageFormat ImageFormat = imageToConvert.RawFormat;
byte[] Ret;
try
{
using (MemoryStream ms = new MemoryStream())
{
imageToConvert.Save(ms, ImageFormat);
Ret = ms.ToArray();
}
}
catch (Exception) { throw; }
return Ret;
You can use File.ReadAllBytes method to get bytes
If you are using FileUpload class then you can use FileBytes Property to get the Bytes as Byte Array.