I have created a 3D game in unity using a asset and I need help changing the save feature so I can save the game in a Sqlite database, any tutorials or videos that could help?
This is the script that is provided to save the game and to load it, im not exactly sure where this is saving to but it seems to save somewhere locally.
using System;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Collections;
using System.Collections.Generic;
using System.Threading.Tasks;
using Newtonsoft.Json.Linq;
using ThunderWire.JsonManager;
using ThunderWire.Helpers;
using HFPS.Prefs;
using UnityEngine;
[Serializable]
public class SaveableDataPair
{
public enum DataBlockType { ISaveable, Attribute }
public DataBlockType BlockType = DataBlockType.ISaveable;
public string BlockKey;
public MonoBehaviour Instance;
public string[] FieldData;
public SaveableDataPair(DataBlockType type, string key, MonoBehaviour instance, string[] fileds)
{
BlockType = type;
BlockKey = key;
Instance = instance;
FieldData = fileds;
}
}
/// <summary>
/// Main script for Save/Load System
/// </summary>
public class SaveGameHandler : Singleton<SaveGameHandler> {
public SaveLoadScriptable SaveLoadSettings;
[Tooltip("Serialize player data between scenes.")]
public bool dataBetweenScenes;
[Tooltip("Not necessary, if you does not want Fade when scene starts or switch, leave this blank.")]
public UIFadePanel fadeControl;
public SaveableDataPair[] saveableDataPairs;
private ItemSwitcher switcher;
private Inventory inventory;
private ObjectiveManager objectives;
private GameObject player;
[HideInInspector]
public string lastSave;
void Start()
{
inventory = GetComponent<Inventory>();
objectives = GetComponent<ObjectiveManager>();
player = GetComponent<HFPS_GameManager>().Player;
switcher = player.GetComponentInChildren<ScriptManager>().GetScript<ItemSwitcher>();
JsonManager.Settings(SaveLoadSettings, true);
if (saveableDataPairs.Any(pair => pair.Instance == null))
{
Debug.LogError("[SaveGameHandler] Some of Saveable Instances are missing or it's destroyed. Please select Setup SaveGame again from the Tools menu!");
return;
}
if (Prefs.Exist(Prefs.LOAD_STATE))
{
int loadstate = Prefs.Game_LoadState();
if(loadstate == 0)
{
DeleteNextLvlData();
}
else if (loadstate == 1 && Prefs.Exist(Prefs.LOAD_SAVE_NAME))
{
string filename = Prefs.Game_SaveName();
if (File.Exists(JsonManager.GetFilePath(FilePath.GameSavesPath) + filename))
{
JsonManager.DeserializeData(filename);
string loadScene = (string)JsonManager.Json()["scene"];
lastSave = filename;
if (UnityEngine.SceneManagement.SceneManager.GetActiveScene().name == loadScene)
{
LoadSavedSceneData(true);
}
}
else
{
Debug.Log("<color=yellow>[SaveGameHandler]</color> Could not find load file: " + filename);
Prefs.Game_LoadState(0);
}
}
else if(loadstate == 2 && Prefs.Exist(Prefs.LOAD_SAVE_NAME) && dataBetweenScenes)
{
JsonManager.ClearArray();
Prefs.Game_SaveName("_NextSceneData.sav");
if (File.Exists(JsonManager.GetFilePath(FilePath.GameDataPath) + "_NextSceneData.sav"))
{
JsonManager.DeserializeData(FilePath.GameDataPath, "_NextSceneData.sav");
LoadSavedSceneData(false);
}
}
}
}
void DeleteNextLvlData()
{
if (File.Exists(JsonManager.GetFilePath(FilePath.GameDataPath) + "_NextSceneData.sav"))
{
File.Delete(JsonManager.GetFilePath(FilePath.GameDataPath) + "_NextSceneData.sav");
}
}
/* SAVE GAME SECTION */
public void SaveGame(bool allData)
{
JsonManager.ClearArray();
Dictionary<string, object> playerData = new Dictionary<string, object>();
Dictionary<string, object> slotData = new Dictionary<string, object>();
Dictionary<string, object> shortcutData = new Dictionary<string, object>();
Dictionary<string, object> objectivesData = new Dictionary<string, object>();
/* PLAYER PAIRS */
if (allData)
{
JsonManager.AddPair("scene", UnityEngine.SceneManagement.SceneManager.GetActiveScene().name);
JsonManager.AddPair("dateTime", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
playerData.Add("playerPosition", player.transform.position);
playerData.Add("cameraRotation", player.GetComponentInChildren<MouseLook>().GetRotation());
}
playerData.Add("playerHealth", player.GetComponent<HealthManager>().Health);
/* END PLAYER PAIRS */
/* ITEMSWITCHER PAIRS */
Dictionary<string, object> switcherData = new Dictionary<string, object>
{
{ "switcherActiveItem", switcher.currentItem },
{ "switcherLightObject", switcher.currentLightObject },
{ "switcherWeaponItem", switcher.weaponItem }
};
foreach (var Item in switcher.ItemList)
{
Dictionary<string, object> ItemInstances = new Dictionary<string, object>();
foreach (var Instance in Item.GetComponents<MonoBehaviour>().Where(x => typeof(ISaveableArmsItem).IsAssignableFrom(x.GetType())).ToArray())
{
ItemInstances.Add(Instance.GetType().Name.Replace(" ", "_"), (Instance as ISaveableArmsItem).OnSave());
switcherData.Add("switcher_item_" + Item.name.ToLower().Replace(" ", "_"), ItemInstances);
}
}
/* END ITEMSWITCHER PAIRS */
/* INVENTORY PAIRS */
foreach (var slot in inventory.Slots)
{
if (slot.GetComponent<InventorySlot>().itemData != null)
{
InventoryItemData itemData = slot.GetComponent<InventorySlot>().itemData;
Dictionary<string, object> itemDataArray = new Dictionary<string, object>
{
{ "slotID", itemData.slotID },
{ "itemID", itemData.item.ID },
{ "itemAmount", itemData.m_amount },
{ "itemData", itemData.customData }
};
slotData.Add("inv_slot_" + inventory.Slots.IndexOf(slot), itemDataArray);
}
else
{
slotData.Add("inv_slot_" + inventory.Slots.IndexOf(slot), "null");
}
}
Dictionary<string, object> inventoryData = new Dictionary<string, object>
{
{ "inv_slots_count", inventory.Slots.Count },
{ "slotsData", slotData }
};
/* INVENTORY SHORTCUTS PAIRS */
if (inventory.Shortcuts.Count > 0)
{
Dictionary<string, object> shortcutsData = new Dictionary<string, object>();
foreach (var shortcut in inventory.Shortcuts)
{
Dictionary<string, object> shortcutsDataPairs = new Dictionary<string, object>
{
{ "itemID", shortcut.item.ID },
{ "shortcutKey", shortcut.shortcutKey.ToString() }
};
shortcutsData.Add("shortcut_" + shortcut.slot, shortcutsDataPairs);
}
inventoryData.Add("shortcutsData", shortcutsData);
}
/* INVENTORY FIXED CONTAINER PAIRS */
if (inventory.FixedContainerData.Count > 0)
{
inventoryData.Add("fixedContainerData", inventory.GetFixedContainerData());
}
/* END INVENTORY PAIRS */
/* OBJECTIVE PAIRS */
if (objectives.objectiveCache.Count > 0)
{
foreach (var obj in objectives.objectiveCache)
{
Dictionary<string, object> objectiveData = new Dictionary<string, object>
{
{ "toComplete", obj.toComplete },
{ "isCompleted", obj.isCompleted }
};
objectivesData.Add(obj.identifier.ToString(), objectiveData);
}
}
/* END OBJECTIVE PAIRS */
//Add data pairs to serialization buffer
JsonManager.AddPair("playerData", playerData);
JsonManager.AddPair("itemSwitcherData", switcherData);
JsonManager.AddPair("inventoryData", inventoryData);
JsonManager.AddPair("objectivesData", objectivesData);
//Add all saveables
if (allData && saveableDataPairs.Length > 0)
{
foreach (var Pair in saveableDataPairs)
{
if(Pair.BlockType == SaveableDataPair.DataBlockType.ISaveable)
{
var data = (Pair.Instance as ISaveable).OnSave();
if (data != null)
{
JsonManager.AddPair(Pair.BlockKey, data);
}
}
else if (Pair.BlockType == SaveableDataPair.DataBlockType.Attribute)
{
Dictionary<string, object> attributeFieldPairs = new Dictionary<string, object>();
if (Pair.FieldData.Length > 0)
{
foreach (var Field in Pair.FieldData)
{
FieldInfo fieldInfo = Pair.Instance.GetType().GetField(Field);
if (fieldInfo.FieldType == typeof(Color) || fieldInfo.FieldType == typeof(KeyCode))
{
if (fieldInfo.FieldType == typeof(Color))
{
attributeFieldPairs.Add(GetAttributeKey(fieldInfo), string.Format("#{0}", ColorUtility.ToHtmlStringRGBA((Color)Pair.Instance.GetType().InvokeMember(Field, BindingFlags.GetField, null, Pair.Instance, null))));
}
else
{
attributeFieldPairs.Add(GetAttributeKey(fieldInfo), Pair.Instance.GetType().InvokeMember(Field, BindingFlags.GetField, null, Pair.Instance, null).ToString());
}
}
else
{
attributeFieldPairs.Add(GetAttributeKey(fieldInfo), Pair.Instance.GetType().InvokeMember(Field, BindingFlags.GetField, null, Pair.Instance, null));
}
}
}
else
{
Debug.LogError("Empty Fields Data: " + Pair.BlockKey);
}
JsonManager.AddPair(Pair.BlockKey, attributeFieldPairs);
}
}
}
//Serialize all pairs from buffer
SerializeSaveData(!allData);
}
/* LOAD SECTION */
void LoadSavedSceneData(bool allData)
{
if (allData)
{
var posToken = JsonManager.Json()["playerData"]["playerPosition"];
player.transform.position = posToken.ToObject<Vector3>();
var rotToken = JsonManager.Json()["playerData"]["cameraRotation"];
player.GetComponentInChildren<MouseLook>().SetRotation(rotToken.ToObject<Vector2>());
}
var healthToken = JsonManager.Json()["playerData"]["playerHealth"];
player.GetComponent<HealthManager>().Health = (float)healthToken;
switcher.currentLightObject = (int)JsonManager.Json()["itemSwitcherData"]["switcherLightObject"];
switcher.weaponItem = (int)JsonManager.Json()["itemSwitcherData"]["switcherWeaponItem"];
//Deserialize ItemSwitcher Item Data
foreach (var Item in switcher.ItemList)
{
JToken ItemToken = JsonManager.Json()["itemSwitcherData"]["switcher_item_" + Item.name.ToLower().Replace(" ", "_")];
foreach (var Instance in Item.GetComponents<MonoBehaviour>().Where(x => typeof(ISaveableArmsItem).IsAssignableFrom(x.GetType())).ToArray())
{
(Instance as ISaveableArmsItem).OnLoad(ItemToken[Instance.GetType().Name.Replace(" ", "_")]);
}
}
//Deserialize ItemSwitcher ActiveItem
int switchID = (int)JsonManager.Json()["itemSwitcherData"]["switcherActiveItem"];
if (switchID != -1)
{
switcher.ActivateItem(switchID);
}
//Deserialize Inventory Data
StartCoroutine(DeserializeInventory(JsonManager.Json()["inventoryData"]));
//Deserialize Objectives
if (JsonManager.HasKey("objectivesData"))
{
Dictionary<int, Dictionary<string, string>> objectivesData = JsonManager.Json<Dictionary<int, Dictionary<string, string>>>(JsonManager.Json()["objectivesData"].ToString());
foreach (var obj in objectivesData)
{
objectives.AddObjectiveModel(new ObjectiveModel(obj.Key, int.Parse(obj.Value["toComplete"]), bool.Parse(obj.Value["isCompleted"])));
}
}
//Deserialize saveables
if (allData)
{
foreach (var Pair in saveableDataPairs)
{
JToken token = JsonManager.Json()[Pair.BlockKey];
if (token == null) continue;
if (Pair.BlockType == SaveableDataPair.DataBlockType.ISaveable)
{
if (Pair.Instance.GetType() == typeof(SaveObject) && (Pair.Instance as SaveObject).saveType == SaveObject.SaveType.ObjectActive)
{
bool enabled = token["obj_enabled"].ToObject<bool>();
Pair.Instance.gameObject.SetActive(enabled);
}
else
{
(Pair.Instance as ISaveable).OnLoad(token);
}
}
else if (Pair.BlockType == SaveableDataPair.DataBlockType.Attribute)
{
foreach (var Field in Pair.FieldData)
{
SetValue(Pair.Instance, Pair.Instance.GetType().GetField(Field), JsonManager.Json()[Pair.BlockKey][GetAttributeKey(Pair.Instance.GetType().GetField(Field))]);
}
}
}
}
}
/* LOAD SECTION INVENTORY */
private IEnumerator DeserializeInventory(JToken token)
{
yield return new WaitUntil(() => inventory.Slots.Count > 0);
int slotsCount = (int)token["inv_slots_count"];
int neededSlots = slotsCount - inventory.Slots.Count;
if(neededSlots != 0)
{
inventory.ExpandSlots(neededSlots);
}
for (int i = 0; i < inventory.Slots.Count; i++)
{
JToken slotToken = token["slotsData"]["inv_slot_" + i];
string slotString = slotToken.ToString();
if (slotString != "null")
{
inventory.AddItemToSlot((int)slotToken["slotID"], (int)slotToken["itemID"], (int)slotToken["itemAmount"], slotToken["itemData"].ToObject<CustomItemData>());
}
}
//Deserialize Shortcuts
if (token["shortcutsData"] != null && token["shortcutsData"].HasValues)
{
Dictionary<string, Dictionary<string, string>> shortcutsData = token["shortcutsData"].ToObject<Dictionary<string, Dictionary<string, string>>>();
foreach (var shortcut in shortcutsData)
{
int slot = int.Parse(shortcut.Key.Split('_')[1]);
inventory.ShortcutBind(int.Parse(shortcut.Value["itemID"]), slot, (KeyCode)Enum.Parse(typeof(KeyCode), shortcut.Value["shortcutKey"]));
}
}
//Deserialize FixedContainer
if (token["fixedContainerData"] != null && token["fixedContainerData"].HasValues)
{
var fixedContainerData = token["fixedContainerData"].ToObject<Dictionary<int, JToken>>();
foreach (var item in fixedContainerData)
{
inventory.FixedContainerData.Add(new ContainerItemData(inventory.GetItem(item.Key), (int)item.Value["item_amount"], item.Value["item_custom"].ToObject<CustomItemData>()));
}
}
}
string GetAttributeKey(FieldInfo Field)
{
SaveableField saveableAttr = Field.GetCustomAttributes(typeof(SaveableField), false).Cast<SaveableField>().SingleOrDefault();
if (string.IsNullOrEmpty(saveableAttr.CustomKey))
{
return Field.Name.Replace(" ", string.Empty);
}
else
{
return saveableAttr.CustomKey;
}
}
void SetValue(object instance, FieldInfo fInfo, JToken token)
{
Type type = fInfo.FieldType;
string value = token.ToString();
if (type == typeof(string)) fInfo.SetValue(instance, value);
if (type == typeof(int)) fInfo.SetValue(instance, int.Parse(value));
if (type == typeof(uint)) fInfo.SetValue(instance, uint.Parse(value));
if (type == typeof(long)) fInfo.SetValue(instance, long.Parse(value));
if (type == typeof(ulong)) fInfo.SetValue(instance, ulong.Parse(value));
if (type == typeof(float)) fInfo.SetValue(instance, float.Parse(value));
if (type == typeof(double)) fInfo.SetValue(instance, double.Parse(value));
if (type == typeof(bool)) fInfo.SetValue(instance, bool.Parse(value));
if (type == typeof(char)) fInfo.SetValue(instance, char.Parse(value));
if (type == typeof(short)) fInfo.SetValue(instance, short.Parse(value));
if (type == typeof(byte)) fInfo.SetValue(instance, byte.Parse(value));
if (type == typeof(Vector2)) fInfo.SetValue(instance, token.ToObject(type));
if (type == typeof(Vector3)) fInfo.SetValue(instance, token.ToObject(type));
if (type == typeof(Vector4)) fInfo.SetValue(instance, token.ToObject(type));
if (type == typeof(Quaternion)) fInfo.SetValue(instance, token.ToObject(type));
if (type == typeof(KeyCode)) fInfo.SetValue(instance, Parser.Convert<KeyCode>(value));
if (type == typeof(Color)) fInfo.SetValue(instance, Parser.Convert<Color>(value));
}
public void SaveNextSceneData(string scene)
{
Prefs.Game_LoadState(2);
Prefs.Game_LevelName(scene);
JsonManager.ClearArray();
SaveGame(false);
}
async void SerializeSaveData(bool betweenScenes)
{
string filepath = JsonManager.GetFilePath(FilePath.GameSavesPath);
GetComponent<HFPS_GameManager>().ShowSaveNotification();
if (!betweenScenes)
{
if (Directory.Exists(filepath))
{
DirectoryInfo di = new DirectoryInfo(filepath);
FileInfo[] fi = di.GetFiles("Save?.sav");
if (fi.Length > 0)
{
string SaveName = "Save" + fi.Length;
lastSave = SaveName + ".sav";
FileStream file = new FileStream(JsonManager.GetCurrentPath() + SaveName + ".sav", FileMode.OpenOrCreate);
await Task.Run(() => JsonManager.SerializeJsonDataAsync(file));
}
else
{
lastSave = "Save0.sav";
FileStream file = new FileStream(JsonManager.GetCurrentPath() + "Save0.sav", FileMode.OpenOrCreate);
await Task.Run(() => JsonManager.SerializeJsonDataAsync(file));
}
}
else
{
Directory.CreateDirectory(JsonManager.GetCurrentPath());
lastSave = "Save0.sav";
FileStream file = new FileStream(JsonManager.GetCurrentPath() + "Save0.sav", FileMode.OpenOrCreate);
await Task.Run(() => JsonManager.SerializeJsonDataAsync(file));
}
Prefs.Game_SaveName(lastSave);
DeleteNextLvlData();
}
else
{
DeleteNextLvlData();
FileStream file = new FileStream(JsonManager.GetFilePath(FilePath.GameDataPath) + "_NextSceneData.sav", FileMode.OpenOrCreate);
await Task.Run(() => JsonManager.SerializeJsonDataAsync(file, true));
}
}
}
Firstly, please research your structure. You have created a game based on an FPS kit, yes? This means that you have a working game, and save features are typically applied with XML or similar formats.
I recommend utilising C# (Unity's native tongue) to implement something like the MySQL Connector for .NET/Mono and translate the elements. I'm not sure if the kit you used has the features baked in, but if you have access to the source (.cs) then you can see where it is saving, and possibly create a DB structure.
What I would look at are the following components:
Table Structure
What are you storing?
The most common components are Inventory items (ammo, life, stamina, consumables, etc.). To store these, perhaps use a loading system to identify each inventory item by a code (like Bethesda's Hex Cell IDs).
How are you storing it? How much data is needed?
Normalisation
Always avoid duplicate values
Always reference things where possible instead of creating a new value (change the value once, change it everywhere)
There's a lot to think about, but before jumping into copying and pasting code, please read up on proper database procedures - it'll help you out a lot :)
Some reading material:
https://medium.com/#rizasif92/sqlite-and-unity-how-to-do-it-right-31991712190
http://findnerd.com/list/view/How-to-save-data-in-SQLite-in-Unity3d/6357/
https://www.essentialsql.com/get-ready-to-learn-sql-database-normalization-explained-in-simple-english/
Best of luck!
I have a parent view and in a partial view with a table when loading the parent view I want to hide the partial as long as the table has no data
public IActionResult Index()
{
try
{
Guayaquil_Turismo.Models.Modelo_Estado_de_Cuenta declaracion = new Models.Modelo_Estado_de_Cuenta();
Guayaquil_Turismo.Models.Valores_a_Pagar Valor_Paga = new Models.Valores_a_Pagar();
List<PernoctaDeclaraciones> ModelDeclaraciones = new List<PernoctaDeclaraciones>();
using (var db = new tecserne_guayaquil_desaContext())
{
System.Security.Claims.Claim claim_Establecimiento = User.Claims.Where(x => x.Type == System.Security.Claims.ClaimTypes.GroupSid).FirstOrDefault();
Valor_Paga = db.Valores_a_Pagar.Where(x => x.IdEstablecimiento == int.Parse(claim_Establecimiento.Value)).FirstOrDefault();
ModelDeclaraciones = db.PernoctaDeclaraciones.Where(x => x.IdEstablecimiento == int.Parse(claim_Establecimiento.Value) && x.EstadoPago == "P").OrderByDescending(x => x.MesDeclaracion).ToList();
foreach (PernoctaDeclaraciones item in ModelDeclaraciones)
{
item.PernoctaMultas.Add(db.PernoctaMultas.Where(x => x.IdDeclaracion == item.IdDeclaracion).FirstOrDefault());
foreach (PernoctaIntereses item2 in db.PernoctaIntereses.Where(x => x.IdDeclaracion == item.IdDeclaracion).ToList().OrderByDescending(x => x.MesInteres))
{
item.PernoctaIntereses.Add(item2);
}
}
declaracion.Declaraciones = ModelDeclaraciones;
declaracion.ValorPaga = Valor_Paga;
return View(declaracion);
}
}
catch (Exception)
{
throw;
}
}
[HttpPost]
public IActionResult Estado_Fecha(string fecha_)
{
List<PernoctaDeclaraciones> obj_fechas = new List<PernoctaDeclaraciones>();
using (var db = new tecserne_guayaquil_desaContext())
{
string[] fechas = fecha_.Split("-");
fechas[0].ToString();
fechas[1].ToString();
DateTime Fechas1 = DateTime.Parse(fechas[0].ToString(), new CultureInfo("en-US", true));
DateTime Fechas2 = DateTime.Parse(fechas[1].ToString(), new CultureInfo("en-US", true));
if (!string.IsNullOrEmpty(fecha_))
{
obj_fechas = db.PernoctaDeclaraciones.Where(x => x.FechaDeclaracion >= Fechas1 & x.FechaDeclaracion <= Fechas2).ToList();
}
}
return View(obj_fechas);
}
If the type of table property in view model is List/Array , you can try
#if (Model.table!= null && Model.table.Count != 0)
{
<partial name="_name" />
}
If the type of table property in view model is IEnumerable , you can try :
#if (Model.table!= null && Model.table.Count() != 0)
{
<partial name="_name" />
}
I am writing an application that must be able to read signed and encrypted emails and parse through their contents. I am able to get everything working fine for emails that are only encrypted, but do not know what to do when I get an email that is also signed. Once I decrypt this email instead of having an anticipated 4 parts in a Multipart object, I have only 1 part in a MimePart object with the file name smime.p7m. I do not know how to break this file up or verify the signature. I have found the documentation on verifying a signature (http://www.mimekit.net/docs/html/Working-With-SMime.htm#Verify), but I don't see how this does anything. Obviously there is something that I am just not understanding at this point.
Below is a sample of the code that I am using. Note that this will be refactored after I get everything figured out, but this code is thus far working fine for all emails that I have tested so far that are not signed (may or may not be encrypted).
public void decryptAndSendEmails()
{
List<EmailMessage> emails = getEmails();
foreach (var email in emails)
{
var decryptedEmailMessage = new EmailMessage(service);
MimeMessage message;
using (var stream = new MemoryStream(email.MimeContent.Content, false))
{
message = MimeMessage.Load(stream);
}
var pkcs7 = message.BodyParts.OfType<ApplicationPkcs7Mime>().FirstOrDefault();
if (pkcs7 != null)
{
//If the SecureMimeType has not been set as it should, set it to EnvelopedData
if (pkcs7.SecureMimeType == SecureMimeType.Unknown)
{
var content = new MemoryStream();
pkcs7.Content.DecodeTo(content);
content.Position = 0;
pkcs7 = new ApplicationPkcs7Mime(SecureMimeType.EnvelopedData, content);
}
using (var ctx = new TemporarySecureMimeContext())
{
using (var stream = File.OpenRead(ConfigurationManager.AppSettings["certLocation"]))
{
ctx.Import(stream, ConfigurationManager.AppSettings["certPassword"]);
}
var decrypted = pkcs7.Decrypt(ctx);
var decryptedParts = new List<MimePart>();
if (decrypted is Multipart)
{
decryptedParts = breakMultiPart((Multipart)decrypted);
}
else if (decrypted is MimePart)
{
decryptedParts.Add((MimePart)decrypted);
}
else
{
throw new InvalidOperationException("Unknown Mime part found");
}
var textParts = decryptedParts.Where(r => r is TextPart);
var htmlParts = textParts.Where(x => ((TextPart)x).IsHtml);
var textBodyParts = textParts.Where(x => !((TextPart)x).IsHtml);
var attachmentParts = decryptedParts.Where(r => !(r is TextPart));
if (htmlParts.Any())
{
if (htmlParts.Count() > 1)
{
throw new InvalidOperationException("multiple html body parts.");
}
var htmlPart = (TextPart)htmlParts.First();
decryptedEmailMessage.Body = new MessageBody(BodyType.HTML, htmlPart.Text);
}
else
{
//Text body
if (textBodyParts.Count() > 1)
{
throw new InvalidOperationException("multiple text body parts.");
}
var textPart = (TextPart)textBodyParts.First();
decryptedEmailMessage.Body = new MessageBody(BodyType.Text, textPart.Text);
}
foreach (var part in attachmentParts)
{
var content = new MemoryStream();
part.Content.DecodeTo(content);
content.Position = 0;
decryptedEmailMessage.Attachments.AddFileAttachment(part.FileName, content);
if (!part.IsAttachment)
{
decryptedEmailMessage.Attachments.First(r => r.Name == part.FileName).IsInline = true;
decryptedEmailMessage.Attachments.First(r => r.Name == part.FileName).ContentId = part.ContentId;
}
}
}
////do stuff with decrypted Email
}
else
{
//The email is not encrypted
decryptedEmailMessage = email;
//do stuff with decrypted Email
}
}
}
I have finally figured this out using a combination of the comment from #jstedfast and the information I found in Unable to decrypt p7m using MimeKit. The following is the resulting code to fix this issue:
public void decryptAndSendEmails()
{
List<EmailMessage> emails = getEmails();
foreach (var email in emails)
{
var decryptedEmailMessage = new EmailMessage(service);
MimeMessage message;
using (var stream = new MemoryStream(email.MimeContent.Content, false))
{
message = MimeMessage.Load(stream);
}
var pkcs7 = message.BodyParts.OfType<ApplicationPkcs7Mime>().FirstOrDefault();
if (pkcs7 != null)
{
using (var ctx = new TemporarySecureMimeContext())
{
using (var stream = File.OpenRead(ConfigurationManager.AppSettings["certLocation"]))
{
ctx.Import(stream, ConfigurationManager.AppSettings["certPassword"]);
}
var decrypted = pkcs7.Decrypt(ctx);
if (decrypted != null && decrypted is MimePart && ((MimePart)decrypted).FileName == "smime.p7m")
{
//We need to verify the signature
var signedDecryptedEntity = decrypted as ApplicationPkcs7Mime;
signedDecryptedEntity.Verify(ctx, out decrypted); //the real decrypted data
}
var decryptedParts = new List<MimePart>();
if (decrypted is Multipart)
{
decryptedParts = breakMultiPart((Multipart)decrypted);
}
else if (decrypted is MimePart)
{
decryptedParts.Add((MimePart)decrypted);
}
else
{
throw new InvalidOperationException("Unknown Mime part found");
}
var textParts = decryptedParts.Where(r => r is TextPart);
var htmlParts = textParts.Where(x => ((TextPart)x).IsHtml);
var textBodyParts = textParts.Where(x => !((TextPart)x).IsHtml);
var attachmentParts = decryptedParts.Where(r => !(r is TextPart));
if (htmlParts.Any())
{
if (htmlParts.Count() > 1)
{
throw new InvalidOperationException("multiple html body parts.");
}
var htmlPart = (TextPart)htmlParts.First();
decryptedEmailMessage.Body = new MessageBody(BodyType.HTML, htmlPart.Text);
}
else
{
//Text body
if (textBodyParts.Count() > 1)
{
throw new InvalidOperationException("multiple text body parts.");
}
var textPart = (TextPart)textBodyParts.First();
decryptedEmailMessage.Body = new MessageBody(BodyType.Text, textPart.Text);
}
foreach (var part in attachmentParts)
{
var content = new MemoryStream();
part.Content.DecodeTo(content);
content.Position = 0;
decryptedEmailMessage.Attachments.AddFileAttachment(part.FileName, content);
if (!part.IsAttachment)
{
decryptedEmailMessage.Attachments.First(r => r.Name == part.FileName).IsInline = true;
decryptedEmailMessage.Attachments.First(r => r.Name == part.FileName).ContentId = part.ContentId;
}
}
}
//Do Something with email (decryptedEmailMessage)
}
else
{
//The email is not encrypted
decryptedEmailMessage = email;
//Do Something with email (decryptedEmailMessage)
}
}
}
We have a requirement that is we need to access onedirve through asp.net/C# and need to get the latest uploaded file..?
Please help me how to solve this type of requirement..?
i tried the following code..
i used following namespaces. but didn't work
using Microsoft.Live.Web.Samples.ConnectAppUserWithMSAccount.Filters;
using Microsoft.Live.Web.Samples.ConnectAppUserWithMSAccount.Models;
private LiveAuthClient MSAuthClient
{
get
{
if (this.liveAuthClient == null)
{
IDictionary<int, string> secretMap = new Dictionary<int, string>();
secretMap.Add(ClientSecretKey, ClientSecret);
this.liveAuthClient = new LiveAuthClient(ClientId, secretMap, null, this);
}
return this.liveAuthClient;
}
}
private MSAccountStatus MSAccountStatus
{
get
{
if (this.msAccountStatus == Controllers.MSAccountStatus.None)
{
using (UsersContext db = new UsersContext())
{
MSAccount msAccount = db.MSAccounts.FirstOrDefault(u => u.UserName == this.User.Identity.Name);
this.msAccountStatus = msAccount != null ? MSAccountStatus.Connected : MSAccountStatus.NotConnected;
}
}
if (this.msAccountStatus == MSAccountStatus.Connected)
{
LiveConnectSession session = this.MSAuthClient.Session;
if (session == null || session.Expires < DateTimeOffset.UtcNow)
{
this.msAccountStatus = MSAccountStatus.ConnectedWithError;
}
}
return this.msAccountStatus;
}
}
I am trying to do a combined add/update function on a many-to-many relationship. DB first. Have three sql tables: Personnel, Orders, PersonnelOrders. Here is my code:
context.ContextOptions.LazyLoadingEnabled = true;
if (saveData.Rows.Count() > 1)
{
foreach (var row in saveData.Rows)
{
if (row != null)
{
var Order_Array = row.Order_Array; //Array of order id's to be used below.
var pData = new Personnel;
{
Personnel_Id = row.Key,
Personnel_Name = row.Name
};
if (pData.Personnel_Id == 0) //ADD
{
foreach (int Id in Order_Array)
{
pData.Orders.Add(new Order() { Order_Id = Id });
}
context.Personnel.AddObject(cvData);
foreach (var j in pData.Orders)
{
context.ObjectStateManager.ChangeObjectState(j, EntityState.Unchanged);
}
}
else //Doesn't error out, but does not work either:
{
pData.Orders.Clear();
foreach (int Id in Order_Array)
{
pData.Orders.Add(new Order() { Order_Id = Id });
}
context.Personnel.Attach(cvData);
context.ObjectStateManager.ChangeObjectState(pData, EntityState.Modified);
}
context.SaveChanges();
}
}
}
return "ok";
EDIT: I got the ADD to work, now I'm stuck on UPDATE. See revised code above.
This is what I had to do to make it work. It looks ugly to me and I'm sure it can be refined, but it works for now.
context.ContextOptions.LazyLoadingEnabled = true; //not sure that this is necessary
if (saveData.Rows.Count() > 1)
{
foreach (var row in saveData.Rows)
{
if (row != null)
{
var Order_Array = row.Order_Array;
if (row.Key == 0) //ADD
{
var pData = new Personnel;
{
Personnel_Id = row.Key, //probably not needed but it doesn't break it
Personnel_Name = row.Name
};
foreach (int Id in Order_Array)
{
var j = context.Orders.Where(c => c.Order_Id == Id).SingleOrDefault();
pData.Orders.Add(j);
}
context.Personnel.AddObject(pData);
foreach (var j in pData.Orders)
{
context.ObjectStateManager.ChangeObjectState(j, EntityState.Unchanged); //so that you don't actually add more orders
}
}
else //UPDATE
{
var ap = context.Personnel.FirstOrDefault(x => x.Personnel_Id == row.Key);
ap.Personnel_Name = row.Name;
ap.Orders.Clear(); //clear out existing associations
foreach (int Id in Order_Array)
{
var j = context.Orders.Where(c => c.Order_Id == Id).SingleOrDefault();
ap.Orders.Add(j); //rebuild new associations
}
}
context.SaveChanges();
}
}
}