Create Multimedia component with Metadata fields.using core service - tridion

I am creating Multimedia components using core service and everything is working fine. But when Metadata schema fields are defined on the Multimedia schema using which I am creating my Multimedia components then I am getting following error:-
Unable to find http://www.tridion.com/ContentManager/5.0/DefaultMultimediaSchema:Metadata.
This message is displayed when I have given Default Multimedia schema's TCM ID for Multimedia component. As metadata fields are saved in Tridion Database so I first have to retrieve these fields from broker or what is the best solution for this, please suggest. Below is the sample code. Please modify it if someone have any idea for providing default value for metadatafields and how to retrieve them (with/without querying broker DB):-
public static string UploadMultiMediaComponent(string folderUri, string title, string schemaID)
{
core_service.ServiceReference1.SessionAwareCoreService2010Client client = new SessionAwareCoreService2010Client();
client.ClientCredentials.Windows.ClientCredential.UserName = "myUserName";
client.ClientCredentials.Windows.ClientCredential.Password = "myPassword"; client.Open();
ComponentData multimediaComponent = (ComponentData)client.GetDefaultData(
ItemType.Component, folderUri);
multimediaComponent.Title = title;
multimediaComponent.ComponentType = ComponentType.Multimedia;
multimediaComponent.Schema.IdRef =schemaID;
//multimediaComponent.Metadata = "";
StreamUpload2010Client streamClient = new StreamUpload2010Client();
FileStream objfilestream = new FileStream(#"\My Documents\images.jpg",
FileMode.Open, FileAccess.Read);
string tempLocation = streamClient.UploadBinaryContent("images.jpg",
objfilestream);
BinaryContentData binaryContent = new BinaryContentData();
binaryContent.UploadFromFile = tempLocation;
binaryContent.Filename = "images.jpg";
binaryContent.MultimediaType = new LinkToMultimediaTypeData()
{
// for jpg file
IdRef = "tcm:0-2-65544"
};
multimediaComponent.BinaryContent = binaryContent;
IdentifiableObjectData savedComponent = client.Save(multimediaComponent,
new ReadOptions());
client.CheckIn(savedComponent.Id, null);
streamClient.Close();
client.Close();
Console.WriteLine(savedComponent.Id);
//}
}

I don't know why your code not working but following code is working for me
public static ComponentData GenerateMultiMediaComponent(TridionGeneration tridionGeneration, XmlData newsArticle, string componentName)
{
try
{
Dictionary<string, object> dicTridion = Common.GetTridionObject(tridionGeneration.client, ItemType.Component, tridionGeneration.Settings.ComponentFolderUri, componentName);
int objectCount = (int)dicTridion["count"];
SchemaFieldsData schemaFields = tridionGeneration.client.ReadSchemaFields(tridionGeneration.Settings.SchemaUri, true, new ReadOptions());
ComponentData componentData = (ComponentData)tridionGeneration.client.GetDefaultData(ItemType.Component, tridionGeneration.Settings.ComponentFolderUri);
if (schemaFields.Fields != null)
{
var fields = Fields.ForContentOf(schemaFields);
Helper.FillSchemaFields(tridionGeneration, fields);
componentData.Content = fields.ToString();
}
if (schemaFields.MetadataFields != null)
{
var metafields = Fields.ForMetadataOf(schemaFields, componentData);
Helper.FillSchemaFields(tridionGeneration, metafields);
componentData.Metadata = metafields.ToString();
}
componentData.Title = (objectCount == 0) ? componentName : componentName + " " + (objectCount + 1).ToString();
componentData.ComponentType = ComponentType.Multimedia;
StreamUpload2010Client streamClient = new StreamUpload2010Client();
FileStream objfilestream = new FileStream(#"[IMAGE_PATH]", FileMode.Open, FileAccess.Read);
string tempLocation = streamClient.UploadBinaryContent("images.jpg", objfilestream);
BinaryContentData binaryContent = new BinaryContentData();
binaryContent.UploadFromFile = tempLocation;
binaryContent.Filename = "[IMAGE_NAME]";
componentData.BinaryContent = binaryContent;
binaryContent.MultimediaType = new LinkToMultimediaTypeData()
{
IdRef = "tcm:0-2-65544"
};
componentData = (ComponentData)tridionGeneration.client.Create(componentData, new ReadOptions());
return componentData;
}
catch (Exception ex)
{
return null;
}
}
Here is the Helper class:
public static class Helper
{
public static void FillSchemaFields(TridionGeneration tridionGeneration, Fields fields)
{
List<XmlData> data = XmlHelper.xmlData;
var ofield = fields.GetEnumerator();
while (ofield.MoveNext())
{
Field f = ofield.Current;
FillFieldValue(tridionGeneration, fields, f, data[0]);
}
}
private static void FillFieldValue(TridionGeneration tridionGeneration, Fields fields, Field f, XmlData data)
{
if (f.Type == typeof(MultimediaLinkFieldDefinitionData))
{
fields[f.Name].Value = tridionGeneration.Settings.DefaultImageUri;
}
else if (f.Type != typeof(EmbeddedSchemaFieldDefinitionData))
{
foreach (XmlData fieldvalue in data.Attributes)
{
if (f.Type == typeof(DateFieldDefinitionData))
{
if (fieldvalue.text.ToLower() == f.Name.ToLower())
{
fields[f.Name].Value = Convert.ToDateTime(fieldvalue.value).ToString("yyyy-MM-ddTHH:mm:ss");
}
else
{
string val = FindSchemaValue(tridionGeneration, fieldvalue.Attributes, f.Name);
if (!string.IsNullOrEmpty(val))
{
fields[f.Name].Value = Convert.ToDateTime(val).ToString("yyyy-MM-ddTHH:mm:ss");
}
}
}
else
{
if (fieldvalue.text.ToLower() == f.Name.ToLower())
{
fields[f.Name].Value = System.Net.WebUtility.HtmlEncode(fieldvalue.value);
}
else
{
string val = FindSchemaValue(tridionGeneration, fieldvalue.Attributes, f.Name);
if (!string.IsNullOrEmpty(val))
{
fields[f.Name].Value = System.Net.WebUtility.HtmlEncode(val);
}
}
}
}
}
else
{
Fields fs = f.GetSubFields();
var ofield = fs.GetEnumerator();
while (ofield.MoveNext())
{
Field ff = ofield.Current;
FillFieldValue(tridionGeneration, fs, ff, data);
}
}
}
private static string FindSchemaValue(TridionGeneration tridionGeneration, List<XmlData> data, string fieldname)
{
foreach (XmlData fieldvalue in data)
{
if (fieldvalue.text.ToLower() == fieldname.ToLower())
{
return fieldvalue.value;
}
else
{
FindSchemaValue(tridionGeneration, fieldvalue.Attributes, fieldname);
}
}
return "";
}
}
and the Fields class:
public class Fields
{
private ItemFieldDefinitionData[] definitions;
private XmlNamespaceManager namespaceManager;
private XmlElement root; // the root element under which these fields live
// at any point EITHER data OR parent has a value
private SchemaFieldsData data; // the schema fields data as retrieved from the core service
private Fields parent; // the parent fields (so we're an embedded schema), where we can find the data
public Fields(SchemaFieldsData _data, ItemFieldDefinitionData[] _definitions, string _content = null, string _rootElementName = null)
{
data = _data;
definitions = _definitions;
var content = new XmlDocument();
if (!string.IsNullOrEmpty(_content))
{
content.LoadXml(_content);
}
else
{
content.AppendChild(content.CreateElement(string.IsNullOrEmpty(_rootElementName) ? _data.RootElementName : _rootElementName, _data.NamespaceUri));
}
root = content.DocumentElement;
namespaceManager = new XmlNamespaceManager(content.NameTable);
namespaceManager.AddNamespace("custom", _data.NamespaceUri);
}
public Fields(Fields _parent, ItemFieldDefinitionData[] _definitions, XmlElement _root)
{
definitions = _definitions;
parent = _parent;
root = _root;
}
public static Fields ForContentOf(SchemaFieldsData _data)
{
return new Fields(_data, _data.Fields);
}
public static Fields ForContentOf(SchemaFieldsData _data, ComponentData _component)
{
return new Fields(_data, _data.Fields, _component.Content);
}
public static Fields ForMetadataOf(SchemaFieldsData _data, RepositoryLocalObjectData _item)
{
return new Fields(_data, _data.MetadataFields, _item.Metadata, "Metadata");
}
public string NamespaceUri
{
get { return data != null ? data.NamespaceUri : parent.NamespaceUri; }
}
public XmlNamespaceManager NamespaceManager
{
get { return parent != null ? parent.namespaceManager : namespaceManager; }
}
internal IEnumerable<XmlElement> GetFieldElements(ItemFieldDefinitionData definition)
{
return root.SelectNodes("custom:" + definition.Name, NamespaceManager).OfType<XmlElement>();
}
internal XmlElement AddFieldElement(ItemFieldDefinitionData definition)
{
var newElement = root.OwnerDocument.CreateElement(definition.Name, NamespaceUri);
XmlNodeList nodes = root.SelectNodes("custom:" + definition.Name, NamespaceManager);
XmlElement referenceElement = null;
if (nodes.Count > 0)
{
referenceElement = (XmlElement)nodes[nodes.Count - 1];
}
else
{
// this is the first value for this field, find its position in the XML based on the field order in the schema
bool foundUs = false;
for (int i = definitions.Length - 1; i >= 0; i--)
{
if (!foundUs)
{
if (definitions[i].Name == definition.Name)
{
foundUs = true;
}
}
else
{
var values = GetFieldElements(definitions[i]);
if (values.Count() > 0)
{
referenceElement = values.Last();
break; // from for loop
}
}
} // for every definition in reverse order
} // no existing values found
root.InsertAfter(newElement, referenceElement); // if referenceElement is null, will insert as first child
return newElement;
}
public IEnumerator<Field> GetEnumerator()
{
return (IEnumerator<Field>)new FieldEnumerator(this, definitions);
}
public Field this[string _name]
{
get
{
var definition = definitions.First<ItemFieldDefinitionData>(ifdd => ifdd.Name == _name);
if (definition == null) throw new ArgumentOutOfRangeException("Unknown field '" + _name + "'");
return new Field(this, definition);
}
}
public override string ToString()
{
return root.OuterXml;
}
}
public class FieldEnumerator : IEnumerator<Field>
{
private Fields fields;
private ItemFieldDefinitionData[] definitions;
// Enumerators are positioned before the first element until the first MoveNext() call
int position = -1;
public FieldEnumerator(Fields _fields, ItemFieldDefinitionData[] _definitions)
{
fields = _fields;
definitions = _definitions;
}
public bool MoveNext()
{
position++;
return (position < definitions.Length);
}
public void Reset()
{
position = -1;
}
object IEnumerator.Current
{
get
{
return Current;
}
}
public Field Current
{
get
{
try
{
return new Field(fields, definitions[position]);
}
catch (IndexOutOfRangeException)
{
throw new InvalidOperationException();
}
}
}
public void Dispose()
{
}
}
public class Field
{
private Fields fields;
private ItemFieldDefinitionData definition;
public Field(Fields _fields, ItemFieldDefinitionData _definition)
{
fields = _fields;
definition = _definition;
}
public string Name
{
get { return definition.Name; }
}
public Type Type
{
get { return definition.GetType(); }
}
public string Value
{
get
{
return Values.Count > 0 ? Values[0] : null;
}
set
{
if (Values.Count == 0) fields.AddFieldElement(definition);
Values[0] = value;
}
}
public ValueCollection Values
{
get
{
return new ValueCollection(fields, definition);
}
}
public void AddValue(string value = null)
{
XmlElement newElement = fields.AddFieldElement(definition);
if (value != null) newElement.InnerText = value;
}
public void RemoveValue(string value)
{
var elements = fields.GetFieldElements(definition);
foreach (var element in elements)
{
if (element.InnerText == value)
{
element.ParentNode.RemoveChild(element);
}
}
}
public void RemoveValue(int i)
{
var elements = fields.GetFieldElements(definition).ToArray();
elements[i].ParentNode.RemoveChild(elements[i]);
}
public IEnumerable<Fields> SubFields
{
get
{
var embeddedFieldDefinition = definition as EmbeddedSchemaFieldDefinitionData;
if (embeddedFieldDefinition != null)
{
var elements = fields.GetFieldElements(definition);
foreach (var element in elements)
{
yield return new Fields(fields, embeddedFieldDefinition.EmbeddedFields, (XmlElement)element);
}
}
}
}
public Fields GetSubFields(int i = 0)
{
var embeddedFieldDefinition = definition as EmbeddedSchemaFieldDefinitionData;
if (embeddedFieldDefinition != null)
{
var elements = fields.GetFieldElements(definition);
if (i == 0 && !elements.Any())
{
// you can always set the first value of any field without calling AddValue, so same applies to embedded fields
AddValue();
elements = fields.GetFieldElements(definition);
}
return new Fields(fields, embeddedFieldDefinition.EmbeddedFields, elements.ToArray()[i]);
}
else
{
throw new InvalidOperationException("You can only GetSubField on an EmbeddedSchemaField");
}
}
// The subfield with the given name of this field
public Field this[string name]
{
get { return GetSubFields()[name]; }
}
// The subfields of the given value of this field
public Fields this[int i]
{
get { return GetSubFields(i); }
}
}

Can you try this?
multimediaComponent.Metadata = "<Metadata/>";

Related

Save unity game in a Sqlite database

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!

Not all InvocationExpression are rewritten

I want to rewrite all InvocationExpression of "MyMethod" in a SyntaxTree to add a literal param 0 with
private class Rewriter : CSharpSyntaxRewriter
{
public int Id { get; set; }
public override SyntaxNode VisitInvocationExpression(InvocationExpressionSyntax node)
{
var invokName = node.Expression.ToString();
if (invokName == "MyMethod")
{
var argus = node.ArgumentList.AddArguments(
SyntaxFactory.Argument(SyntaxFactory.LiteralExpression(SyntaxKind.NumericLiteralExpression, SyntaxFactory.Literal(Id))));
return node.Update((ExpressionSyntax)Visit(node.Expression), argus);
}
return node;
}
}
static void Main(string[] args)
{
SyntaxTree oriTree = CSharpSyntaxTree.ParseText(#"
public class MyClass
{
public string MyMethod(int id)
{
return $""{id}"";
}
public void Say()
{
var tmp = MyMethod();//worked
var tmp1 = MyMethod();//worked
var tmp2 = ""Hi "" + MyMethod();//worked
Console.WriteLine($""Say {MyMethod()}"");//Not worked
Console.WriteLine(""Hello "" + MyMethod());//Not worked
}
}");
var syntaxRoot = oriTree.GetCompilationUnitRoot();
var visitor = new Rewriter();
visitor.Id = 0;
var changedSyntaxTree = visitor.Visit(syntaxRoot).SyntaxTree;
}
But not all are rewritten.
With
var methods = syntaxRoot.DescendantNodes().OfType<InvocationExpressionSyntax>().Where(o => o.Expression.ToString() == "MyMethod");
I can enumerate all InvocationExpression of "MyMethod". But I don't know how to change syntax tree without CSharpSyntaxRewriter.
How can I do it? Thanks.
It Solved based on CyrusNajmabadi's reply
you need to do this instead:
public override SyntaxNode VisitInvocationExpression(InvocationExpressionSyntax node)
{
node = (InvocationExpressionSyntax)base.VisitInvocationExpression(node);
// now, the rest of your code:
var invokName = node.Expression.ToString();
// etc.
Thanks CyrusNajmabadi!

Dapper: Mapping dynamic pivot columns from stored procedure

My stored procedure is returning dynamic pivot columns as available. I am using the SQLMapper and COlumnTypeAttribute, But in the results I can only see the first column and its value, but the dynamic pivot column(s) and their values(s) are empty.
the sample data could look like
The first column is fixed, Rest of the columns are pivot columns.
TSBNumber SystemXY SystemBB SystemTT
asdas 1/1/2013
1231 1/1/2014
12312 1/1/2013
ASAWS 1/1/2013
awsdS 1/1/2013
Store Procedure
DECLARE #PivotColumnHeaders NVARCHAR(MAX)
SELECT #PivotColumnHeaders =
COALESCE(
#PivotColumnHeaders + ',[' + cast(SystemFullName as Nvarchar) + ']',
'[' + cast(SystemFullName as varchar)+ ']'
)
FROM System
WHERE (#SelectedSystemIDs IS NULL OR System.ID IN(select * from dbo.SplitInts_RBAR_1(#SelectedSystemIDs, ',')))
AND ((#PlatformID IS NULL) OR (System.PlatformID = #PlatformID) OR (#PlatformID = 12 AND System.PlatformID <= 2))
DECLARE #PivotTableSQL NVARCHAR(MAX)
SET #PivotTableSQL = N'
SELECT *
FROM (
SELECT
TSBNumber [TSBNumber],
SystemFullName,
ClosedDate
FROM ServiceEntry
INNER JOIN System
ON ServiceEntry.SystemID = System.ID
where
(ServiceEntry.TSBNumber IS NOT NULL)
AND
(ServiceEntry.ClosedDate IS NOT NULL)
AND
(
(''' + #SelectedTsbIDs + ''' = '''+ '0' + ''') OR
(ServiceEntry.TSBNumber in (select * from dbo.SplitStrings_Moden(''' + #SelectedTsbIDs + ''', ''' + ',' + ''')))
)
) AS PivotData
PIVOT (
MAX(ClosedDate)
FOR SystemFullName IN (
' + #PivotColumnHeaders + '
)
) AS PivotTable
'
EXECUTE (#PivotTableSQL)
ColumnAttributeTypeManager
namespace RunLog.Domain.Exports
{
/// <summary>
/// Uses the Name value of the ColumnAttribute specified, otherwise maps as usual.
/// </summary>
/// <typeparam name="T">The type of the object that this mapper applies to.</typeparam>
public class ColumnAttributeTypeMapper<T> : FallbackTypeMapper
{
public static readonly string ColumnAttributeName = "ColumnAttribute";
public ColumnAttributeTypeMapper()
: base(new SqlMapper.ITypeMap[]
{
new CustomPropertyTypeMap(
typeof(T),
(type, columnName) =>
type.GetProperties().FirstOrDefault(prop =>
prop.GetCustomAttributes(false)
.OfType<ColumnAttribute>()
.Any(attr => attr.Name == columnName)
)
),
new DefaultTypeMap(typeof(T))
})
{
}
//public ColumnAttributeTypeMapper()
// : base(new SqlMapper.ITypeMap[]
// {
// new CustomPropertyTypeMap(typeof (T), SelectProperty),
// new DefaultTypeMap(typeof (T))
// })
//{
//}
//private static PropertyInfo SelectProperty(Type type, string columnName)
//{
// return
// type.GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance).
// FirstOrDefault(
// prop =>
// prop.GetCustomAttributes(false)
// // Search properties to find the one ColumnAttribute applied with Name property set as columnName to be Mapped
// .Any(attr => attr.GetType().Name == ColumnAttributeName
// &&
// attr.GetType().GetProperties(BindingFlags.Public |
// BindingFlags.NonPublic |
// BindingFlags.Instance)
// .Any(
// f =>
// f.Name == "Name" &&
// f.GetValue(attr).ToString().ToLower() == columnName.ToLower()))
// && // Also ensure the property is not read-only
// (prop.DeclaringType == type
// ? prop.GetSetMethod(true)
// : prop.DeclaringType.GetProperty(prop.Name,
// BindingFlags.Public | BindingFlags.NonPublic |
// BindingFlags.Instance).GetSetMethod(true)) != null
// );
//}
}
public class MyModel
{
[Column("TSBNumber")]
public string TSBNumber { get; set; }
[Column(Name = "FileKey")]
public string MyProperty2 { get; set; }
//public string MyProperty2 { get; set; } // Uses Default Mapping
// ...
}
[AttributeUsage(AttributeTargets.Property, AllowMultiple = true)]
public class ColumnAttribute : Attribute
{
public string Name { get; set; }
public ColumnAttribute() { }
public ColumnAttribute(string Name) { this.Name = Name; }
}
public class FallbackTypeMapper : SqlMapper.ITypeMap
{
private readonly IEnumerable<SqlMapper.ITypeMap> _mappers;
public FallbackTypeMapper(IEnumerable<SqlMapper.ITypeMap> mappers)
{
_mappers = mappers;
}
public ConstructorInfo FindConstructor(string[] names, Type[] types)
{
foreach (var mapper in _mappers)
{
try
{
ConstructorInfo result = mapper.FindConstructor(names, types);
if (result != null)
{
return result;
}
}
catch (NotImplementedException)
{
}
}
return null;
}
public SqlMapper.IMemberMap GetConstructorParameter(ConstructorInfo constructor, string columnName)
{
foreach (var mapper in _mappers)
{
try
{
var result = mapper.GetConstructorParameter(constructor, columnName);
if (result != null)
{
return result;
}
}
catch (NotImplementedException)
{
}
}
return null;
}
public SqlMapper.IMemberMap GetMember(string columnName)
{
foreach (var mapper in _mappers)
{
try
{
var result = mapper.GetMember(columnName);
if (result != null)
{
return result;
}
}
catch (NotImplementedException)
{
}
}
return null;
}
}
}
Executing Stored Procedure
public static string ServiceTsbExport(DateTime StartDate, DateTime EndDate, int UserRoleID,
string SelectedSystemIDs,
string SelectedTsbIDs)
{
EFDbContext db = new EFDbContext();
Dapper.SqlMapper.SetTypeMap(typeof(MyModel), new ColumnAttributeTypeMapper<MyModel>());
return db.Database.SqlQuery<MyModel>("[dbo].[spExportServiceTSB] #parm1, #parm2, #parm3, #parm4, #parm5",
new SqlParameter("parm1", StartDate),
new SqlParameter("parm2", EndDate),
new SqlParameter("parm3", SelectedSystemIDs),
new SqlParameter("parm4", SelectedTsbIDs),
new SqlParameter("parm5", UserRoleID)
).ToList().ToHTMLTable();
}
I think you're making this very hard while it could be simple. I've once done almost exactly the same thing. Here's an anonymized version of it:
using Dapper;
...
using (var cnn = new SqlConnection(#"Data Source=... etc."))
{
cnn.Open();
var p = new DynamicParameters();
p.Add("#params", "Id=21");
var obs = cnn.Query(sql:"GetPivotData", param: p,
commandType:CommandType.StoredProcedure);
var dt = ToDataTable(obs);
}
This ToDataTable method is probably similar to your ToHTMLTable method. Here it is:
public DataTable ToDataTable(IEnumerable<dynamic> items)
{
if (items == null) return null;
var data = items.ToArray();
if (data.Length == 0) return null;
var dt = new DataTable();
foreach(var pair in ((IDictionary<string, object>)data[0]))
{
dt.Columns.Add(pair.Key, (pair.Value ?? string.Empty).GetType());
}
foreach (var d in data)
{
dt.Rows.Add(((IDictionary<string, object>)d).Values.ToArray());
}
return dt;
}
The heart of the logic is that the dynamic returned by Dapper's Query() extension method can be cast to an IDictionary<string, object>.

Event Up-Conversion With Keeping Event-Class Name

NEventStore 3.2.0.0
As far as I found out it is required by NEventStore that old event-types must kept around for event up-conversion.
To keep them deserializing correctly in the future they must have an unique name. It is suggested to call it like EventEVENT_VERSION.
Is there any way to avoid EventV1, EventV2,..., EventVN cluttering up your domain model and simply keep using Event?
What are your strategies?
In a question long, long time ago, an answer was missing...
In the discussion referred in the comments, I came up with an - I would say - elegant solution:
Don't save the type-name but an (versioned) identifier
The identifier is set by an attribute on class-level, i.e.
namespace CurrentEvents
{
[Versioned("EventSomethingHappened", 0)] // still version 0
public class EventSomethingHappened
{
...
}
}
This identifier should get serialized in/beside the payload. In serialized form
"Some.Name.Space.EventSomethingHappened" -> "EventSomethingHappened|0"
When another version of this event is required, the current version is copied in an "legacy" assembly or just in another Namespace and renamed (type-name) to "EventSomethingHappenedV0" - but the Versioned-attribute remains untouched (in this copy)
namespace LegacyEvents
{
[Versioned("EventSomethingHappened", 0)] // still version 0
public class EventSomethingHappenedV0
{
...
}
}
In the new version (at the same place, under the same name) just the version-part of the attribute gets incremented. And that's it!
namespace CurrentEvents
{
[Versioned("EventSomethingHappened", 1)] // new version 1
public class EventSomethingHappened
{
...
}
}
Json.NET supports binders which maps type-identifiers to types and back. Here is a production-ready binder:
public class VersionedSerializationBinder : DefaultSerializationBinder
{
private Dictionary<string, Type> _getImplementationLookup = new Dictionary<string, Type>();
private static Type[] _versionedEvents = null;
protected static Type[] VersionedEvents
{
get
{
if (_versionedEvents == null)
_versionedEvents = AppDomain.CurrentDomain.GetAssemblies()
.Where(x => x.IsDynamic == false)
.SelectMany(x => x.GetExportedTypes()
.Where(y => y.IsAbstract == false &&
y.IsInterface == false))
.Where(x => x.GetCustomAttributes(typeof(VersionedAttribute), false).Any())
.ToArray();
return _versionedEvents;
}
}
public VersionedSerializationBinder()
{
}
private VersionedAttribute GetVersionInformation(Type type)
{
var attr = type.GetCustomAttributes(typeof(VersionedAttribute), false).Cast<VersionedAttribute>().FirstOrDefault();
return attr;
}
public override void BindToName(Type serializedType, out string assemblyName, out string typeName)
{
var versionInfo = GetVersionInformation(serializedType);
if (versionInfo != null)
{
var impl = GetImplementation(versionInfo);
typeName = versionInfo.Identifier + "|" + versionInfo.Revision;
}
else
{
base.BindToName(serializedType, out assemblyName, out typeName);
}
assemblyName = null;
}
private VersionedAttribute GetVersionInformation(string serializedInfo)
{
var strs = serializedInfo.Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries);
if (strs.Length != 2)
return null;
return new VersionedAttribute(strs[0], strs[1]);
}
public override Type BindToType(string assemblyName, string typeName)
{
if (typeName.Contains('|'))
{
var type = GetImplementation(GetVersionInformation(typeName));
if (type == null)
throw new InvalidOperationException(string.Format("VersionedEventSerializationBinder: No implementation found for type identifier '{0}'", typeName));
return type;
}
else
{
var versionInfo = GetVersionInformation(typeName + "|0");
if (versionInfo != null)
{
var type = GetImplementation(versionInfo);
if (type != null)
return type;
// else: continue as it is a normal serialized object...
}
}
// resolve assembly name if not in serialized info
if (string.IsNullOrEmpty(assemblyName))
{
Type type;
if (typeName.TryFindType(out type))
{
assemblyName = type.Assembly.GetName().Name;
}
}
return base.BindToType(assemblyName, typeName);
}
private Type GetImplementation(VersionedAttribute attribute)
{
Type eventType = null;
if (_getImplementationLookup.TryGetValue(attribute.Identifier + "|" + attribute.Revision, out eventType) == false)
{
var events = VersionedEvents
.Where(x =>
{
return x.GetCustomAttributes(typeof(VersionedAttribute), false)
.Cast<VersionedAttribute>()
.Where(y =>
y.Revision == attribute.Revision &&
y.Identifier == attribute.Identifier)
.Any();
})
.ToArray();
if (events.Length == 0)
{
eventType = null;
}
else if (events.Length == 1)
{
eventType = events[0];
}
else
{
throw new InvalidOperationException(
string.Format("VersionedEventSerializationBinder: Multiple types have the same VersionedEvent attribute '{0}|{1}':\n{2}",
attribute.Identifier,
attribute.Revision,
string.Join(", ", events.Select(x => x.FullName))));
}
_getImplementationLookup[attribute.Identifier + "|" + attribute.Revision] = eventType;
}
return eventType;
}
}
...and the Versioned-attribute
[AttributeUsage(AttributeTargets.Class)]
public class VersionedAttribute : Attribute
{
public string Revision { get; set; }
public string Identifier { get; set; }
public VersionedAttribute(string identifier, string revision = "0")
{
this.Identifier = identifier;
this.Revision = revision;
}
public VersionedAttribute(string identifier, long revision)
{
this.Identifier = identifier;
this.Revision = revision.ToString();
}
}
At last use the versioned binder like this
JsonSerializer.Create(new JsonSerializerSettings
{
TypeNameHandling = TypeNameHandling.All,
TypeNameAssemblyFormat = FormatterAssemblyStyle.Simple,
Binder = new VersionedSerializationBinder()
});
For a full Json.NET ISerialize-implementation see (an little outdated) gist here:
https://gist.github.com/warappa/6388270

Flex 3: Getting variables from URL

If I have an application located at http://sitename.com/myapp/ and i want to pass in a variable via the url (i.e. - http://sitename.com/myapp/?name=Joe), how can I get that name variable into a string var?
I use the class Adobe provided in this article.
package
{
import flash.external.*;
import flash.utils.*;
public class QueryString
{
private var _queryString:String;
private var _all:String;
private var _params:Object;
public function get queryString():String
{
return _queryString;
}
public function get url():String
{
return _all;
}
public function get parameters():Object
{
return _params;
}
public function QueryString()
{
readQueryString();
}
private function readQueryString():void
{
_params = {};
try
{
_all =
ExternalInterface.call("window.location.href.toString");
_queryString =
ExternalInterface.call("window.location.search.substring", 1);
if(_queryString)
{
var params:Array = _queryString.split('&');
var length:uint = params.length;
for (var i:uint=0,index:int=-1; i 0)
{
var key:String = kvPair.substring(0,index);
var value:String = kvPair.substring(index+1);
_params[key] = value;
}
}
}
}catch(e:Error) { trace("Some error occured.
ExternalInterface doesn't work in Standalone player."); }
}
}
}
UPDATE: An updated version of this class can also be found here, although I haven't tried this one.
UPDATE 2:
Here's an example on how to use the Querystring class:
public function CheckForIDInQuerystring():void
{
// sample URL: http://www.mysite.com/index.aspx?id=12345
var qs:QueryString = new QueryString;
if (qs.parameters.id != null)
{
// URL contains the "id" parameter
trace(qs.parameters.id);
}
else
{
// URL doesn't contain the "id" parameter
trace("No id found.");
}
}
Divide 'em with String.split() and conquer:
var url:String = "http://www.xxx.zzz/myapp?arg1=vae&arg2=victus";
var params:String = url.substr(url.lastIndexOf("?") + 1);
if (params.length == url.length) return; //no params
for each (var pair:String in params.split("&"))
{
trace("Got parameter:");
var nameValue:Array = pair.split("=");
trace("name: " + nameValue[0] + ", value: " + nameValue[1]);
}
Output:
Got parameter:
name: arg1, value: vae
Got parameter:
name: arg2, value: victus

Resources