How to update a Dictionary entry in ClearScript? - c#

Context: ClearScript, JScript, C#, Windows, Azure
In my ClearScript-enabled projects, I have a Dictionary<string,object> that I use for passing data into, around inside and back out of evaluated scripts.
On the C# side I have
static Dictionary<string, object> Settings = new Dictionary<string, object>();
and then later on
JSengine = new JScriptEngine(WindowsScriptEngineFlags.EnableDebugging | WindowsScriptEngineFlags.EnableJITDebugging);
and
JSengine.AddHostObject("CSSettings", Settings);
On the JScript side I have things like
CSSettings.Add("your API key", CSConfig.Retrieve("api.key"));
for setting values.
The challenge at the moment is updating a value in the Dictionary. The following works
CSSettings.Item("id") = Wfm_AccNumber;
it's just that it's non-standard JScript. What's more the JSHint tool that I'm using inside of Notepad++ complains.
I could do a .Remove() before the .Add(), I suppose but is there a better way?

The following should work:
CSSettings.Item.set("id", Wfm_AccNumber);
value = CSSettings.Item.get("id"); // or CSSettings.Item("id")
This may look a bit clunky, but it's standard JavaScript and should work with all .NET indexers (which aren't always named "Item", and can have more than one parameter).

Related

Dynamically creating C# Dictionary<Cottle.Value, Cottle.Value> from json using System.Text.JSON without foreach

I’m trying to create an object of Dictionary<Cottle.Value, Cottle.Value> (Cottle is a templating engine that uses it’s own type for storing keys and values to replace {key} text with values in a template) from a json string that doesn’t have nested values so that each and any pair of json key/values gets converted to a dictionary keyvaluepair…but the best I’ve managed to do so far is create a Dictionary<string, string> thus leaving me with the problem of creating Cottle.Value from string which can actually be done by calling Value.FromString(string) but doing that requires going through a foreach loop, so I’m just wondering is there a more direct way to do that? TIA
P.S.
Unfortunately, I’m not using Newtonsoft to create a custom converter and may have missed the way to the same with System.Text.JSON so that could be an easiest solution if still possible but seems too complicated for a simple thing I’m trying to do…adding it to a webapi.

Dealing with a JSON.Net JArray in Python?

I'm using IronPython as a scripting language in my C# application. One of the "features" that I've implemented is the ability for a script to persist values, which are then exposed to the next script being executed. This is achieved by passing the value(s) to be stored to a C# class, exposed to the script by the "host" application. The code to store a value looks something like this:
store.set("xyz", 123)
('store' is the variable through which the C# object is exposed).
Internally the C# class stores these name/value pairs in a Dictionary<string, object>. When the script finishes executing it serialises the dictionary using Json.Net (var json = JsonConvert.SerializeObject(dict)) and writes the resulting string to file.
When the next script is run, the "host" C# application reads and deserialises the file (JsonConvert.DeserializeObject<Dictionary<string, object>>(s)) and exposes the name/value pairs to the script via the same C# class, which the script can access like this:
my_var = store.get("xyz")
This feature has been working fine with simple types such as ints and floats, but one of our users now needs to persist a list of ints. It works to a fashion - the list gets persisted and exposed to the next Python script, but at this point it is now a JArray type (something to do with Json.Net it seems). This doesn't play nicely with the Python code (which is expecting a list of ints).
I guess the simplest fix is to convert this JArray to a Python int list. But how?
Alternatively it would be nice if the issue could be "fixed" in the C# class (casting?), to avoid users from having to do this conversion in their scripts. However I don't want to change the de/serialisation process to the extent that it no longer reads users' existing data files. Thoughts?
I've found a solution with only minimal impact on script authors. In my C# code, after deserialising the file, I go through the dictionary looking for items with a value of type JArray, and convert them to arrays:
var dict = JsonConvert.DeserializeObject<Dictionary<string, object>>(json);
var keys = dict.Keys.ToList();
foreach (var key in keys)
{
var jarray = dict[key] as JArray;
if (jarray != null)
{
dict[key] = jarray.ToObject<object[]>();
}
}
These arrays are then exposed to the Python script as before; as they are C# arrays the script authoer must convert to Python lists, which is trivial:
my_var = list(store.get("xyz"))

Objective-C converting to C#: How can I use a .plist with multiple types in C# if Dictionary is strongly-typed?

The question is a bit complicated so I will try and explain. I have a custom .plist (XML Property List) file I created with Xcode. Within it is many different types of data: NSDictionary, NSArray, NSString, BOOL, etc.
Here's an example:
In my code I can quickly obtain an NSDictionary of this entire file without knowing an data types using the following code (this is ARC code by the way). The only data types that I DO know of is that all of the keys are strings, but the values can be anything I've shown above:
+ (NSDictionary *)configDictionary
{
collectorstemplateAppDelegate *appDelegate = (collectorstemplateAppDelegate*)
[[UIApplication sharedApplication] delegate];
NSString *path = [[NSBundle mainBundle]
pathForResource:appDelegate.currentPlist ofType:#"plist"];
NSDictionary *dict = [[NSDictionary alloc] initWithContentsOfFile:path];
return dict;
}
What I am trying to do is to accomplish the same thing on C#. I'd like to take these plists and move them to my Windows Phone phone apps, keeping the same structure. I realize that I will need to write some additional code to handle the XML behind the file, but you get the idea.... I want a Dictionary or HashTable or Collection of something similar to what I've done above, without knowing the types of the values.
Obviously in my case something like Dictionary<string, string> isn't going to work for me.
Any help would be great.
Answering my own question here but looking for validation....
Would Dictionary<string, object> work? Because I know the key is a string, I would just need to cast the value to the appropriate type, correct?
int appleID = (int) plistDict["appleid"];
If this is correct or incorrect, someone please let me know.
Hashtable is a non-generic version of Dictionary. In other words it doesn't require you to specify the types it deals with, and you can cash like you would in Objective-C.

Dynamic object properties in C# and Javascript

I have a table in the database for various settings in my application. These settings can be added to or changed at any time. I would like to pull them out of the db into an object and reference them in both my server code (C#) and client code (JS).
SettingGroup SettingName type value
Core defaultPagingSize numeric 5
Core pagingType text dynamic
Ecommerce showGallery boolean true
In javascript I can just put them into a JSON object and reference them like this:
var size = settings.core.defaultPagingSize;
Is there a similar way I can do this in C#?
int size = settings.core.defaultPagingSize;
No.
The new dynamic keyword that will be added for .NET and C# 4.0 will handle what you're seeking, but in the current .NET and C# versions, there's no support for this.
You should be able to get this to work though:
int size = settings["core"]["defaultPagingSize"].ToInt32();
or something similar.
In .NET, the most immediate answer would be to use a dictionary (perhaps nested) of some kind. C# 4.0 introduces some dynamic concepts, but you'd need to write a fair bit of code to get it to behave like javascript.
Alternatively, store them as typed records in a flat list and use LINQ:
var setting = settings.Single(x=>x.Group == "Core"
&& x.Name == "defaultPagingSize");
int value = int.Parse(setting.Value);

Referencing Embedded resources from other resources in c#

In my web application I include all of my JavaScripts as js files that are embedded resources in the assembly, and add them to the page using ClientScriptManager.GetWebResourceUrl(). However, in some of my js files, I have references to other static assets like image urls. I would like to make those assembly resources as well. Is there a way to tokenize the reference to the resource? e.g.
this.drophint = document.createElement('img');
this.drophint.src = '/_layouts/images/dragdrophint.gif';
Could become something like:
this.drophint = document.createElement('img');
this.drophint.src = '{resource:assembly.location.dragdrophint.gif}';
I'd suggest that you emit the web resources as a dynamic javascript associative array.
Server side code:
StringBuilder script = new StringBuilder();
script.Append("var imgResources = {};");
script.AppendFormat("imgResources['{0}'] = '{1}';",
"drophint",
Page.ClientScript.GetWebResourceUrl(Page.GetType(), "assembly.location.dragdrophint.gif"));
script.AppendFormat("imgResources['{0}'] = '{1}';",
"anotherimg",
Page.ClientScript.GetWebResourceUrl(Page.GetType(), "assembly.location.anotherimg.gif"));
Page.ClientScript.RegisterClientScriptBlock(
Page.GetType(),
"imgResources",
script.ToString(),
true);
Then your client side code looks like this:
this.drophint = document.createElement('img');
this.drophint.src = imgResources['drophint'];
this.anotherimg = document.createElement('img');
this.anotherimg.src = imgResources['anotherimg'];
Hope this helps.
I don't particularly care for the exact implementation #Jon suggests, but the idea behind it is sound and I would concur that emitting these would be a good thing to do.
A slightly better implementation, though this is all subjective to some degree, would be to create a server-side model (read: C# class(es)) that represents this dictionary (or simply use an instance of Dictionary<string, string>) and serialize that to JavaScript literal object notation. That way you are not dealing with the string hacking you see in Jon's example (if that bothers you).
I concur with Jason's assessment of the initial solution I proposed, it can definitely be improved. My solution represents an older school javascript mentality (read, pre the emergence of ajax and JSON). There are always better ways to solve a problem, which one of the reasons why StackOverflow is so cool. Collectively we are better at the craft of programming than anyone of us on our own.
Based on Jason's ideas I'd revise my initial code, and revise some of what Jason suggested. Implement a C# class with two properties, the img resource id and a property that contains the WebResourceUrl. Then, where I differ some from Jason is that rather than using a Dictionary<string, string> I'd propose using a List<MyImageResourceClass>, which you can then in turn serialize to JSON (using DataContractJsonSerializer), and emit the JSON as the dynamic script, rather than manually generating the javascript using a string builder.
Why a List? I think you may find that dictionaries when serialized to JSON, at least using the DataContractJsonSerializer (fyi available with the 3.5 framework only, with the 2.0 or 3.0 framework you'd need to bolt on aspnet ajax and use is JSON serializer), are a little more cumbersome to work with than how a list would serialize. Although that is subjective.
There are implications too with your client side code. Now on the client side you'll have an array of the JSON serialized MyImageResourceClass instances. You'd need to iterate through this array creating your img tags as you go.
Hopefully, these ideas and suggestions can help get you going! And no doubt there are other solutions. I'm interested to see what comes of this.

Categories

Resources