Smartly replace strings - c#

I am working with JSON API. As c# doesn't accept characters like - (minus) or . (point), I had to replace each character by _ (underscore). The replacement happens when the JSON response is received as a string so that every attribute name containing a - or a . will have it replaced by a _ , then every attribute name will be the same as the attributes names in the class it will be deserialized into.
To make it clearer, here are some examples:
I recieve the following JSON : { "id": 1, "result": [ { "data": [ { "adm-pass": ""}]}
In the class I want to deserialize into I have this attribute : public String adm_pass {get; set;}
So I replace the minus with an underscore so that the NewtonSoft parser can deserialize it accordingly.
My problem is that I sometimes I get some negative integers in my JSON. So if I do the string replacement in: {"beta" : -1}, I get a parsing exception since the -1 (integer here) becomes _1 and cannot be deserialized properly and raises an exception.
Is there a way to replace the string smartly so I can avoid this error?
For example if - is followed by an int it's not replaced.
If this way does not exist, is there a solution for this kind of problems?

Newtonsoft allows you to specify the exact name of the JSON property, which it will use to serialize/deserialize.
So you should be able to do this
[JsonProperty("adm-pass")]
public String adm_pass { get; set; }
This way you are not restricted to name your properties exactly as the JSON property names. And in your case, you won't need to do a string replace.
Hope this helps.

You'll have to check that you are replacing the key and not the value, maybe by using a regex like http://regexr.com/3d471

Regex could work as wlalele suggests.
But I would create a new object like this:
Create a new object:
var sharpObj = {};
loop through the objects as properties as described here:
Iterate through object properties
for (var property in object) {
if (object.hasOwnProperty(property)) {
// do stuff
}
}
In the // do stuff section, create a property on sharpObj with the desired string replacements and set the property to the same value.
var cleanProperty = cleanPropertyName(property);
sharpObj[cleanProperty] = orginalObject[property];
Note: I assume you can figure out the cleanPropertyName() method or similar.
Stringify the object
var string = JSON.stringify(sharpObj);

You can substring to check whether the next character is an integer, this can adapt into your code easily as you already find a character, as such you could do
int a;
if(int.TryParse(adm_pass.Substring(adm_pass.IndexOf("-") + 1,1),out a))
{
//Code if next character is an int
}
else
{
adm_pass = adm_pass.Replace("-","_");
}
This kind of code can be looped until there are no remaining hyphens/minuses

Related

c# ignoring { in strings

I'm trying to learn c# Json.net and I want to create a JSON multiline string that includes string declarations, but the first curly bracket which is meant to be part of the JSON dictionary is including itself in the declaration. It errors me on the 'name', if anyone can please give me a solution that would be great.
here is the code.
string Name = "'Name'";
string Is_Airing = "True";
string Genre_One = "'Yes'";
string Genre_Two = "'No'";
string Json_String = $#"{
'Name': '{Name}',
'Is_Airing': {Is_Airing},
'Genres': [
'{Genre_One}',
'{Genre_Two}'
]
}";
If your heart is set on DIY, double up the brackets to escape {{, but you're really [doing a poor job of] reinventing the wheel compared to using a serializer and chucking something like an anonymous or proper type into it:
//newtonsoft
JsonConvert.SerializeObject(new {
Name, //gets name of property from name of variable
Is_Airing = MyIsAiringVariableName, //specifies name of property in anonymous type
Genres = new []{
Genre_One,
Genre_Two
}
});
'Name': '{Name}',
JSON uses double quotes, by the way.. And typically uses camelCase names. Usign a serializer will ensure better compliance with standard JSON ("be strict in what you send and liberal in what you accept")
For more control over how the output JSON appears, you set options on the serializer (such as passing Formatting.Indented as the second argument to SerializeObject), or decorate your properties with attributes
The Newtonsoft documentation is quite comprehensive and includes useful samples to get you going: https://www.newtonsoft.com/json/help/html/SerializeObject.htm

Extract Values from JObject

I'm trying to extract some values from a Json but I have problems with the data between [ ]
{
attrib1: ""es-BO"",
attrib2: 2,
Segment: [
{
inAttrib1: ""value1"",
inAttrib2: ""value2"",
inAttrib3: ""value3""
}]
}
for the first values I'm using:
string attrib1 = request.GetValue("attrib1").Value<string>();
.
.
.
but when I'm trying to do:
string inAttrib1 = request.GetValue("inAttrib1").Value<string>();
doesn't work...what can I do?, or exists another way to do the same
The data between (and including) [] is called an array. Before moving on it might be helpful to look at JSON's home page, specifically at the different data types available.
You need to navigate down to the Segment array, then get the first element, then that element's inAttrib1 property:
string attrib1Value = request["Segment"][0]["inAttrib1"].Value<string>();
Or alternatively:
string attrib1Value = request.SelectToken(#"Segment[0].inAttrib1").Value<string>()

Json.NET, can SerializeXmlNode be extended to detect numbers?

I am converting from XML to JSON using SerializeXmlNode. Looks the expected behavior is to convert all XML values to strings, but I'd like to emit true numeric values where appropriate.
// Input: <Type>1</Type>
string json = JsonConvert.SerializeXmlNode(node, Newtonsoft.Json.Formatting.Indented, true);
// Output: "Type": "1"
// Desired: "Type": 1
Do I need to write a custom converter to do this, or is there a way to hook into the serialization process at the appropriate points, through delegates perhaps? Or, must I write my own custom JsonConverter class to manage the transition?
Regex Hack
Given the complexity of a proper solution, here is another (which I'm not entirely proud of, but it works...).
// Convert to JSON, and remove quotes around numbers
string json = JsonConvert.SerializeXmlNode(node, Newtonsoft.Json.Formatting.Indented, true);
// HACK to force integers as numbers, not strings.
Regex rgx = new Regex("\"(\\d+)\"");
json = rgx.Replace(json, "$1");
XML does not have a way to differentiate primitive types like JSON does. Therefore, when converting XML directly to JSON, Json.Net does not know what types the values should be, short of guessing. If it always assumed that values consisting only of digits were ordinal numbers, then things like postal codes and phone numbers with leading zeros would get mangled in the conversion. It is not surprising, then, that Json.Net takes the safe road and treats all values as string.
One way to work around this issue is to deserialize your XML to an intermediate object, then serialize that to JSON. Since the intermediate object has strongly typed properties, Json.Net knows what to output. Here is an example:
class Program
{
static void Main(string[] args)
{
string xml = #"<root><ordinal>1</ordinal><postal>02345</postal></root>";
XmlSerializer xs = new XmlSerializer(typeof(Intermediary));
using (TextReader reader = new StringReader(xml))
{
Intermediary obj = (Intermediary)xs.Deserialize(reader);
string json = JsonConvert.SerializeObject(obj , Formatting.Indented);
Console.WriteLine(json);
}
}
}
[XmlRoot("root")]
public class Intermediary
{
public int ordinal { get; set; }
public string postal { get; set; }
}
Output of the above:
{
"ordinal": 1,
"postal": "02345"
}
To make a more generic solution, yes, you'd have to write your own converter. In fact, the XML-to-JSON conversion that takes place when calling SerializeXmlNode is done using an XmlNodeConverter that ships with Json.Net. This converter itself does not appear to be very extensible, but you could always use its source code as a starting point to creating your own.

Passing parameters though url?

I am trying to test a call to my one of my functions.
This is called from outside of my website an acts like a Webservice.
To test im trying to pass the parameters though my url.
http://localhost:0000/APIService/UploadValuationDetails?ValuationDetails=[{property_details_address_address1{TagValue:'Test'},{ImageBase64:''}}]?Id=4785
My code in my service:
public void UploadValuationDetails(Dictionary<string, ValuationDetails> JsonResult, int Id)
{
DatabaseHelper DBH = new DatabaseHelper();
foreach (var item in JsonResult)
{ //(ValuationId , TagName , TagValue , ImageBase64)
DBH.WSValuationDetailUpdate(Id, item.Key, item.Value.TagValue, item.Value.ImageBase64);
}
}
ValuationDetails class:
public class ValuationDetails
{
public string TagValue { get; set; }
public string ImageBase64 { get; set; }
}
Edit Changed ? for the second parameter to &:
> http://localhost:0000/APIService/UploadValuationDetails?ValuationDetails={'property_details_address_address1':[{TagValue:'Test',ImageBase64:''}]}&Id=4785
After changing my url to the one above a break point was hit but the values were incorrect.
Edit 2 Trying to get the correct values in the json result.
I think i'm closer:
http://localhost:0000/APIService/UploadValuationDetails?JsonResult={TagName:"property_details_address_address1",ValuationDetails:{TagValue:"Test","ImageBase64:""}}]&Id=4785
But now my jsonResult = 0
You should use an ampersand (&) to separate multiple query string parameters. As you have it, you're using ?, so "?Id=4785" is being interpreted as part of the value for the ValuationDetails parameter.
Corrected:
this is correct ┐
↓
http://localhost:0000/APIService/UploadValuationDetails?ValuationDetails=
[{property_details_address_address1{TagValue:'Test'},{ImageBase64:''}}]&Id=4785
↑
but this should be fixed ┘
I think it is better to Encode the JSON too.
Since the moment you will have for instance in side your data an ? or & you will get an exception too.
Your URL string looks improperly formatted.
For the separator of the URL and the parameters you would use ?.
But to separate parameters use &
http://localhost:0000/APIService/UploadValuationDetails?ValuationDetails=[{property_details_address_address1{TagValue:'Test'},{ImageBase64:''}}]&Id=4785
Your JSON is invalid.
I've worked with it a bit, but it still needs input from you.
[
{
"property_details_address_address1": {
"TagValue": "Test"
},
"needs_a_name_here": {
"ImageBase64": ""
}
}
]
Notice that i've put quotes around the names. And your second object also requires a name.
I used JSONLint to validate and create the proper json

using strings in c#.net

Hi How do I retrieve the number from the following string,
{"number":100,"data":[test]}
The number could be of any length.
I used the following code. but it gives and error message
strValue.Substring((strValue.IndexOf(":")+1), (strValue.IndexOf("data")));
the output comes like
100,"data":[
Thanks,
It looks like your input string is JSON. Is it? If so, you should use a proper JSON parser library like JSON.NET
As noted by Jon, your input string seems to be a JSON string which needs to be deserialized. You can write your own deserializer, or use an existing library, such as Json.NET. Here is an example:
string json = #"[
{
""Name"": ""Product 1"",
""ExpiryDate"": ""\/Date(978048000000)\/"",
""Price"": 99.95,
""Sizes"": null
},
{
""Name"": ""Product 2"",
""ExpiryDate"": ""\/Date(1248998400000)\/"",
""Price"": 12.50,
""Sizes"": null
}
]";
List<Product> products = JsonConvert.DeserializeObject<List<Product>>(json);
Your attempt is close. There are two (possibly three issues) I found.
Your string has a comma after the number you're looking for. Since your code is searching for the index of "data", your end index will end up one character too far.
The second paramter of String.Substring(int, int) is actually a length, not an end index.
Strings are immutable in C#. Because of this, none of the member functions on a string actually modify its value. Instead, they return a new value. I don't know if your code example is complete, so you may be assigning the return value of SubString to something, but if you're not, the end result is that strValue remains unchanged.
Overall, the result of your current call to string.Substring is returning 100,"data":[tes. (and as far as I can see, it's not storing the result).
Try the following code:
string justTheNumber = null;
// Make sure we get the correct ':'
int startIndex = strValue.IndexOf("\"number\":") + 9;
// Search for the ',' that comes after "number":
int endIndex = strValue.IndexOf(',', startIndex);
int length = endIndex - startIndex;
// Note, we could potentially get an ArguementOutOfRangeException here.
// You'll want to handle cases where startPosition < 0 or length < 0.
string justTheNumber = strValue.Substring(startIndex, length);
Note: This solution does not handle if "number": is the last entry in the list inside your string, but it should handle every other placement in it.
If your strings get more complex, you could try using Regular Expressions to perform your searches.
Parsing JSON spring in that way is very bad practice as everything is hardcoded. Have you though of using 3rd party library for parsing JSON strings, like Newtonsoft JSON.
I guess you needed to use IndexOf(",") istead of IndexOf("data")

Categories

Resources