I am porting an old game to Windows 10 store app.
I can write and then read string to app settings:
ApplicationDataContainer^ localSettings = ApplicationData::Current->LocalSettings;
localSettings->Values->Insert("keyS", "hello");
String^ valueS = safe_cast<String^>(localSettings->Values->Lookup("keyS"));
I also can put int value:
localSettings->Values->Insert("keyI", 123);
But how do I read it?
??? valueI = safe_cast<???>(localSettings->Values->Lookup("keyI"));
Lookup returns Platform::Object^, so how do I cast it to int?
It is an IBox -- the equivalent of "nullable" in .NET.
auto localSettings = ApplicationData::Current->LocalSettings;
localSettings->Values->Insert(L"forty-two", (int)42);
auto forty_two = static_cast<Platform::IBox<int>^>
(localSettings->Values->Lookup(L"forty-two"));
if (forty_two != nullptr)
{
int value = forty_two->Value;
// use value
}
Related
I inherited some old Interop code and wanted to update it for the newer guidance, as it uses StringBuilder.
https://learn.microsoft.com/en-us/dotnet/standard/native-interop/best-practices
I do not have access to the source code to the native method.
[DllImport(NativeLib, CharSet = CharSet.Ansi, ExactSpelling = true)]
static extern int native_func(double input, StringBuilder result);
public string Convert(double input)
{
var res = new StringBuilder();
if (native_func(input, res) == 0)
return res.ToString();
throw ...;
}
I was able to convert things to manually use AllocateHGlobal instead of StringBuilder.
[DllImport(NativeLib, CharSet = CharSet.Ansi, ExactSpelling = true)]
static extern int native_func(double input, IntPtr result);
public string Convert(input val)
{
var res = Marshal.AllocHGlobal(100);
// pretend we are calling Marshal.FreeHGlobal later...
if (native_func(input, res) == 0)
return Marshal.PtrToStringAnsi(res);
throw ...;
}
But that's not the new ref/span/etc hotness.
However, no matter what I seem to try for the result parameter, I either get just the first character, or a System.AccessViolationException.
I've tried MemoryMarshal.GetReference, I've tried pinning, I've tried ref-ing, I've tried out-ing; whenever I'm trying to use a managed buffer, it just doesnt' work.
Are there scenarios where the new interop just doesn't work? Is AllocHGlobal the best I can do?
Can we handle null value output from json.decode? I already try using if else function, but it doesn't really works well.
import 'dart:convert';
var typeCat = "WrongKey";
var endPoint = "WrongKey";
void main() async {
final base = RetryClient(http.Client());
String outputJSON = await base.read(
Uri.parse("http://estra-api.herokuapp.com/api/${typeCat}/${endPoint}"));
final link_decode = json.decode(outputJSON)["link"] as String;
final text_decode = json.decode(outputJSON)["text"] as String;
print(link_decode);
print(text_decode);
}
Is there anything I can do with these codes?
I can't be 100% sure since you didn't share the full error message, but the problem seem to be that you're trying to cast to a non-nullable String a value that can possibly be null.
final link_decode = json.decode(outputJSON)["link"] as String?;
final text_decode = json.decode(outputJSON)["text"] as String?;
and if you want to assign a default value for them you can also:
final link_decode = json.decode(outputJSON)["link"] ?? 'default';
final text_decode = json.decode(outputJSON)["text"] ?? 'default';
This will allow link_decode and text_decode to have null as value
Try this and if you don't succede share the error message.
public string GetQCAsync(string UserLimit)
{
var DSet1 = _context.test.Where(x => x.Uid == 1).FirstOrDefault();
var provider = new System.Security.Cryptography.RSACryptoServiceProvider();
//provider.ImportParameters("aXb2uy4z");
DSet1.NoOfUsers = provider.Encrypt(
System.Text.Encoding.UTF8.GetBytes(UserLimit), true);
string decryptedTest = System.Text.Encoding.UTF8.GetString(
provider.Decrypt(DSet1.NoOfUsers, true));
return decryptedTest;
}
i tried this but this won't work
i want to get integer value and to encrypt it and save the encrypted value in sql while saving and i have to get the actual[decrypted] value when edit
I met a blocking issue when I tried to immigrate my project from Windows Phone Silverlight 8.1 to Windows Runtime.
In Windows Runtime the AES-encrypted string is not the same as the one on Silverlight before.
In Silverlight:
public static string EncryptAES(string encryptString)
{
AesManaged aes = null;
MemoryStream ms = null;
CryptoStream cs = null;
string encryptKey = "testtest123";
string salt = "abcabcabcd";
try
{
Rfc2898DeriveBytes rfc2898 = new Rfc2898DeriveBytes(encryptKey, Encoding.UTF8.GetBytes(salt));
aes = new AesManaged();
aes.Key = rfc2898.GetBytes(aes.KeySize / 8);
aes.IV = rfc2898.GetBytes(aes.BlockSize / 8);
ms = new MemoryStream();
cs = new CryptoStream(ms, aes.CreateEncryptor(), CryptoStreamMode.Write);
byte[] data = Encoding.UTF8.GetBytes(encryptString);
cs.Write(data, 0, data.Length);
cs.FlushFinalBlock();
return Convert.ToBase64String(ms.ToArray());
}
catch
{
return encryptString;
}
finally
{
if (cs != null)
cs.Close();
if (ms != null)
ms.Close();
if (aes != null)
aes.Clear();
}
}
In Windows Runtime:
public static string EncryptAES(string plainText)
{
string pw = "testtest123";
string salt = "abcabcabcd";
IBuffer plainBuffer = CryptographicBuffer.ConvertStringToBinary(plainText, BinaryStringEncoding.Utf8);
IBuffer saltBuffer = CryptographicBuffer.ConvertStringToBinary(salt, BinaryStringEncoding.Utf8);
IBuffer pwBuffer = CryptographicBuffer.ConvertStringToBinary(pw, BinaryStringEncoding.Utf8);
KeyDerivationAlgorithmProvider keyDerivationProvider = Windows.Security.Cryptography.Core.KeyDerivationAlgorithmProvider.OpenAlgorithm(KeyDerivationAlgorithmNames.Pbkdf2Sha256);
// using salt and 1000 iterations
KeyDerivationParameters pbkdf2Parms = KeyDerivationParameters.BuildForPbkdf2(saltBuffer, 1000);
// create a key based on original key and derivation parmaters
CryptographicKey keyOriginal = keyDerivationProvider.CreateKey(pwBuffer);
IBuffer keyMaterial = CryptographicEngine.DeriveKeyMaterial(keyOriginal, pbkdf2Parms, 32);
CryptographicKey derivedPwKey = keyDerivationProvider.CreateKey(pwBuffer);
// derive buffer to be used for encryption salt from derived password key
IBuffer saltMaterial = CryptographicEngine.DeriveKeyMaterial(derivedPwKey, pbkdf2Parms, 16);
// display the buffers - because KeyDerivationProvider always gets cleared after each use, they are very similar unforunately
string keyMaterialString = CryptographicBuffer.EncodeToBase64String(keyMaterial);
string saltMaterialString = CryptographicBuffer.EncodeToBase64String(saltMaterial);
//AES_CBC_PKCS7
SymmetricKeyAlgorithmProvider symProvider = SymmetricKeyAlgorithmProvider.OpenAlgorithm("AES_CBC_PKCS7");
// create symmetric key from derived password key
CryptographicKey symmKey = symProvider.CreateSymmetricKey(keyMaterial);
// encrypt data buffer using symmetric key and derived salt material
IBuffer resultBuffer = CryptographicEngine.Encrypt(symmKey, plainBuffer, saltMaterial);
string result = CryptographicBuffer.EncodeToBase64String(resultBuffer);
return result;
}
In Silverlight Project, string "123456" encrypted by AES is "4UfdhC/0MFQlMhl7N7gqLg==";
While in Windows Runtime Project, the AES-encrypted string is "jxsR5EuhPXgRsHLs4N3EGQ=="
So how can I get the same string on WinRT as the one on Silverlight ?
The AES classes default to a random IV on the Microsoft runtimes. To get the same ciphertext you'll need to use a static IV. That's however not secure. Instead you should just check if you get the same key bytes and let the ciphertext differ for each run. Otherwise you can clearly distinguish identical plaintext.
You also seem to be using the wrong hash algorithm, Rfc2898DeriveBytes uses SHA-1 instead of SHA-256 as underlying hash function.
I've created class which works for me as replacement for System.Security.Cryptography.Rfc2898DeriveBytes:
public class Rfc2898DeriveBytes
{
private readonly string _password;
private readonly byte[] _salt;
public Rfc2898DeriveBytes(string password, byte[] salt)
{
_password = password;
_salt = salt;
IterationCount = 1000;
}
public uint IterationCount { get; set; }
public byte[] GetBytes(uint cb)
{
var provider = KeyDerivationAlgorithmProvider.OpenAlgorithm(KeyDerivationAlgorithmNames.Pbkdf2Sha1);
var buffSecret = CryptographicBuffer.ConvertStringToBinary(_password, BinaryStringEncoding.Utf8);
var buffsalt = CryptographicBuffer.CreateFromByteArray(_salt);
var keyOriginal = provider.CreateKey(buffSecret);
var par = KeyDerivationParameters.BuildForPbkdf2(buffsalt, IterationCount);
var keyMaterial = CryptographicEngine.DeriveKeyMaterial(keyOriginal, par, cb);
byte[] result;
CryptographicBuffer.CopyToByteArray(keyMaterial, out result);
return result;
}
}
I implemented a generic solution for using lazy loading primefaces datatables using JPA Criterea.
However I am still having some doubts with thie implemented solution whenever we deal with several Joins (say for example an entity User that has relation with other entities like Account, Address, Department.....in addition to raw type properties like: String username, Date birthdate...etc).
I tested this solution but I am having some delays while loading huge number of data (however the solution is supposed to load only a limited number of rows specified by PageSize coming from datatable), so:
How to improve the performance of this solution?
How to be sure the number of loaded data is the one specified in the Pagesize?
Can you check the count() method and tell if it counts the number of result rows without loading all the data?
And most importantly how to use this solution in order to be generic with filters coming from Search forms (I mean how to use this sae generic method and give search critereas from a search form with multi search fields)?
Please I need your answer on the above mentioned questions especially the last one.
Here is the code:
public <T extends Object> List<T> search(Class<T> type, int first, int pageSize, String sortField, SortOrder sortOrder, Map<String, String> filters){
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<T> q = cb.createQuery(type);
Root<T> root=q.from(type);
q.select(root);
//Sorting
if (sortField != null && !sortField.isEmpty()) {
String[] sortingField = sortField.split("\\.", 2);
Path path = sortingField.length == 1 ? root.get(sortingField[0]): root.join(sortingField[0]).get(sortingField[1]);
if (sortOrder.equals(SortOrder.ASCENDING)) {
q.orderBy(cb.asc(path));
} else if (sortOrder.equals(SortOrder.DESCENDING)) {
q.orderBy(cb.desc(path));
}
}
// Filtering
Predicate filterCondition = cb.conjunction();
String wildCard = "%";
for (Map.Entry<String, String> filter : filters.entrySet()) {
String[] filterField = filter.getKey().split("\\.", 2);
Path path = filterField.length == 1 ? root.get(filterField[0]): root.join(filterField[0]).get(filterField[1]);
filterCondition = cb.and(filterCondition, filter.getValue().matches("[0-9]+")
? cb.equal(path, Long.valueOf(filter.getValue()))
: cb.like(path, wildCard + filter.getValue() + wildCard));
}q.where(filterCondition);
//Pagination
TypedQuery<T> s = entityManager.createQuery(q);
if (pageSize >= 0){
s.setMaxResults(pageSize);
}
if (first >= 0){
s.setFirstResult(first);
}
log.info("\n\n\n");
log.info("XXXXXXXXXxX");
log.info("=> CommonRepository - Total number of rows returned: ");
log.info("XXXXXXXXXXX");
log.info("\n\n\n");
return s.getResultList();
}
public <T extends Object> int count(Class<T> type, Map<String, String> filters){
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<Long> cq = cb.createQuery(Long.class);
Root<T> root=cq.from(type);
// Filtering
Predicate filterCondition = cb.conjunction();
String wildCard = "%";
for (Map.Entry<String, String> filter : filters.entrySet()) {
String[] filterField = filter.getKey().split("\\.", 2);
Path path = filterField.length == 1 ? root.get(filterField[0]): root.join(filterField[0]).get(filterField[1]);
filterCondition = cb.and(filterCondition, filter.getValue().matches("[0-9]+")
? cb.equal(path, Long.valueOf(filter.getValue()))
: cb.like(path, wildCard + filter.getValue() + wildCard));
}cq.where(filterCondition);
cq.select(cb.count(root));
return entityManager.createQuery(cq).getSingleResult().intValue();
}