2

I have a JSON object with numerous properties that I am submitting to a C# web service via jQuery.ajax() - it looks something like this:

var obj = {};
obj.LanguageCode = 1031;
obj.Gender = { 'Geschlecht': 'Mann' };
obj.City = { 'Stadt': 'Berlin' };
...

Some properties, like Gender and City, store a localized/translated prompt and response that I want to map to a KeyValuePair. I've tried formatting the Javascript in different ways, but the data only comes through when the datatype is Dictionary - when the datatype is KeyValuePair it doesn't work. For example:

private Dictionary Gender { get; set; } // works: Gender[0] == {[Geschlecht,Mann]}
private KeyValuePair City { get; set; } // doesn't work: City == {[,]}

I can use Dictionary if necessary since it works, but it seems like KeyValuePair is more appropriate and cleaner to use. Can you map Javascript objects to KeyValuePairs, or am I stuck with using Dictionary?

John Saunders
  • 160,644
  • 26
  • 247
  • 397
emo
  • 43
  • 1
  • 5
  • If you want to map to a `KeyValuePair` without further translation you actually need to match the C# structure's property names - `{ "Key": "Geschlecht", "Value": "Mann" }` – Jamie Treworgy Mar 12 '13 at 20:00
  • Thanks, Jamie - that was a combination I has tried also. Just tried it again, and the VS debugger shows the Key and Value are null. – emo Mar 12 '13 at 22:20

1 Answers1

1

Looks like you need a collection of KeyValuePair objects, not a single one (even though your collection would only have one item) - that's all a Dictionary is, a collection with a few helpers around it.

But personally, I'd recommend building an actual class to represent your values, to organize it a little better - a little more verbose, but I think it's worth it.

// C#
public class LocalAndTranslated {
    public string Localized { get;set; }
    public string Translated { get;set; }
}

// JS
obj.Gender = { Localized: "Geschlecht", Translated: "Man" };

If you wanted to, you can even go so far as to define a "class" in javascript:

var LocalAndTranslated = (function() {
    function LocalAndTranslated(localized, translated) {
        this.Localized = localized;
        this.Translated = translated;
    }
    return LocalAndTranslated;
})();

obj.Gender = new LocalAndTranslated("Geschlecht", "Man");
Joe Enos
  • 39,478
  • 11
  • 80
  • 136
  • Thanks, Joe - I had actually tried something like that, but couldn't get it to work. I was taking a shortcut that I think would be the same as the JS class you described:obj.Gender = { Localized:"Geschlecht", Translated:"Man" } Isn't that the same thing? – emo Mar 12 '13 at 19:58
  • Yep, you don't actually need the "class" in javascript - defining the plain JS object like you've got is fine. All depends on your coding style - I kind of like defining classes, makes it a little bit safer, since you don't have to worry about spelling things right - the class definition defines the properties, so whatever you pass in the constructor is guaranteed to make it to the right place. – Joe Enos Mar 12 '13 at 20:02
  • I tested your example, and see a slightly different result in the VS debugger - the LocalAndTranslated instances have null values for the Localized and Translated properties. It should work as you've described, so must be missing something obvious - I'll keep hacking away and post the solution when I have it figured out. – emo Mar 12 '13 at 22:16
  • Take a look at your raw request in Fiddler to see what you're actually posting. Actually I don't think you mentioned if this was WCF, ASMX, or WebAPI - but whichever it is, it's probably just the method parameter name being missed when it's needed, or included when it's not. – Joe Enos Mar 12 '13 at 22:29
  • While this answer isn't the solution to the OP, I'm accepting it because this is the workaround I chose. Jamie's suggestion looked like it should work, and Fiddler showed a valid JSON string being sent to the service, but I couldn't set a value for a KeyValuePair datatype using any of the syntax I tried. String, int, Dictionary and custom classes all worked fine, so I ended up creating a helper class that emulated a KeyValuePair like this answer does. – emo Mar 13 '13 at 12:24