Create JSON object from Multiline textbox windows phone - c#

In my windows phone app, I'm in a need of creating a JSON object dynamically. i.e. I will know the property names only during run time. Also the property values can contain multiple lines.
Previously when I had to include multiple lines in a JSON object without any problem I used the following.
MemoryStream ms = new MemoryStream();
DataContractJsonSerializer ser = new DataContractJsonSerializer(obj.GetType());
ser.WriteObject(ms, obj);
using (StreamReader sr = new StreamReader(ms))
{
ms.Position = 0;
input = sr.ReadToEnd();
}
return input;
This worked very fine. But in order to use I should've known the class before hand. Unfortunately it is not possible.
Can anyone help me with any work around ?
Thank you.

DataContractJsonSerializer does not support such things.
You should try, for instance, Json.net.

Related

Can I add a CustomXmlPart to my presentation without storing the XML for it in a file?

TLDR; Please either confirm that the 2nd code snippit is the accepted method for creating a CustomXmlPart or show me another less tedious method.
So I'm trying to embed some application data in some of the elements in a .pptx that I'm modifying using the OpenXmlSDK.
To explain briefly, I need to embed an chart code into each image that is loaded into the presentation. It's so that the presentation can be re-uploaded and the charts can be generated again then replaced using the newest data.
Initially I was using Extended Attributes on the OpenXmlElement itself:
//OpenXmlDrawing = DocumentFormat.OpenXml.Drawing
// there's only one image per slide for now, so I just grab the blip which contains the image
OpenXmlDrawing.Blip blip = slidePart.Slide.Descendants<OpenXmlDrawing.Blip>().FirstOrDefault();
//then apply the attribute
blip.SetAttribute(new OpenXmlAttribute("customAttribute", null, customAttributeValue));
The issue with that being, when the .pptx is edited in PowerPoint 2013, it strips out all the Extended Attributes.
SO.
I've read in multiple places now that the solution is to use a CustomXmlPart.
So I was trying to find how to do it.. and it was looking like it would require me to have a separate file for each CustomXmlPart to feed into the part. Ex/
var customXmlPart = slidePart.AddCustomXmlPart(CustomXmlPartType.CustomXml);
using (FileStream stream = new FileStream(fileName, FileMode.Open))
{
customXmlPart.FeedData(stream);
}
^ and that would need to be repeated with a different file for each CustomXmlPart. Which then means I'd likely just have to have a template file containing a skeleton custom XML part, and then dynamically fill in its contents for each individual slide before feeding it into the custom xml part.
It seems like a heck of a lot of work just to put in a little custom attribute. But I haven't been able to find any alternative methods.
Can anyone please either confirm that this is indeed the way I should do it, or point me in another direction? Greatly appreciated.
The answer is yes! :)
public class CustomXMLPropertyClass
{
public string PropertyName { get; set; }
public string PropertyValue { get; set; }
}
private static void AddCustomXmlPartCustomPropertyToSlidePart(string propertyName, string propertyValue, SlidePart part)
{
var customXmlPart = part.AddCustomXmlPart(CustomXmlPartType.CustomXml);
var customProperty = new CustomXMLPropertyClass{ PropertyName = propertyName, PropertyValue = propertyValue };
var serializer = new System.Xml.Serialization.XmlSerializer(customProperty.GetType());
var stream = new MemoryStream();
serializer.Serialize(stream, customProperty);
var customXml = System.Text.Encoding.UTF8.GetString(stream.ToArray());
using ( var streamWriter = new StreamWriter(customXmlPart.GetStream()))
{
streamWriter.Write(customXml);
streamWriter.Flush();
}
}
and then to get it back out:
private static string GetCustomXmlPropertyFromCustomXmlPart(CustomXmlPart customXmlPart)
{
var customXmlProperty = new CustomXMLPropertyClass();
string xml = "";
using (var stream = customXmlPart.GetStream())
{
var streamReader = new StreamReader(stream);
xml = streamReader.ReadToEnd();
}
using (TextReader reader = new StringReader(xml))
{
var serializer = new System.Xml.Serialization.XmlSerializer(typeof(customXmlProperty));
customXmlProperty = (CustomXMLPropertyClass)serializer.Deserialize(reader);
}
var customPropertyValue = customXmlProperty.PropertyValue;
return customPropertyValue;
}
You could also try custom properties. Custom XML files are meant for complex objects, and it sounds like you only need to store simple information.

Replacing Template Fields in Word Documents with OpenXML

I am trying to create a templating system with OpenXML in our Azure app service-based application (so no Interop) and am running into issues with getting it to work. Here is the code I am currently working with (contents is a byte array):
using(MemoryStream stream = new MemoryStream(contents))
{
using (WordprocessingDocument wordDoc = WordprocessingDocument.Open(stream, true))
{
string docText = null;
using (StreamReader sr = new StreamReader(wordDoc.MainDocumentPart.GetStream()))
{
docText = sr.ReadToEnd();
}
Regex regexText = new Regex("<< Company.Name >>");
docText = regexText.Replace(docText, "Company 123");
using (StreamWriter sw = new StreamWriter(wordDoc.MainDocumentPart.GetStream(FileMode.Create)))
{
sw.Write(docText);
}
wordDoc.Save();
}
updated = stream.ToArray();
}
The search text is not being found/replaced, which I am assuming is because of the way everything is stored separately in the XML, but how would I go about replacing a field like this?
Thanks
Ryan
With OpenXML SDK you can use this SearchAndReplace - Youtube, note that it's a screen cast that shows the algorithm that can be used to accomplish the replacement over multiple <w:run> elements.
An alternative approach would be to use pure .NET solution, like this Find and Replace text in a Word document.
Last, the easiest and straightforward approach would be to use some other library, for instance check this example of Find and Replace with GemBox.Document.

Get JSON from website then parse it in C#

So there is 1 website from where I need to get this JSON data.
The link is direct (I am using the website's API )
THe problem is, the file is HUGE!. Tens of Thousands of Lines.. Even more..
I have visual studio 2013 and what I need to do is download that JSON data in a callback and then parse it to get a specific value. I am using Newtonsoft.JSON to parse it and here is what I have thought will be able to parse it
var obj = JsonConvert.DeserializeObject<JContainer>(jsonText);
var value = (int)obj["response"]["prices"]["5021"]["6"]["0"]["current"]["value"];
The problem is, how do I download all of that data and convert it into C# classes? Is there another way?
Thanks a lot.
EDIT: If not JSON, I have option to download it in JSONP and VDF format
Here is the link of the JSON data - http://backpack.tf/api/IGetPrices/v3/?format=json&key=52f75dab4dd7b82f698b4568
I got it working by doing this
using (var webClient = new System.Net.WebClient())
{
var json = webClient.DownloadString("http://backpack.tf/api/IGetPrices/v3/?format=json&key=00a00aaa0aa0a00a000a0000");
Newtonsoft.Json.Linq.JObject o = Newtonsoft.Json.Linq.JObject.Parse(json);
var value = (int)o["response"]["prices"]["5021"]["6"]["0"]["current"]["value"];
Console.WriteLine(value);
}
Thanks for your help everybody!!
Try restsharp. It let you do something like
var prices = client.Execute<Prices>(request);
Where Prices is the class that matches the returned schema
Looking at the comment Brandon posted, he's right in principle, but you don't have to switch to Newtonsoft if you don't want. You just need to use a different JSON.NET API
var serializer = new JsonSerializer();
using (var stream = File.OpenRead("C:\\Users\\gweakliem\\Downloads\\sotest.js"))
{
using (StreamReader streamReader = new StreamReader(stream))
{
using (JsonReader reader = new JsonTextReader(streamReader))
{
var aThing = serializer.Deserialize<JContainer>(reader);
var aValue = (int) aThing["response"]["prices"]["5021"]["6"]["0"]["current"]["value"];
Console.WriteLine("Read a value " + aValue);
}
}
}
If you're concerned about blocking on this thread while reading, it looks like you're going to have to write some code. I don't see awaitable methods on JsonTextReader or JsonSerializer, so I expect that those methods will block.
Now if you want to turn this into objects, here's a couple other SO posts:
deserialize json into .net object using json.net
dynamic JContainer (JSON.NET) & Iterate over properties at runtime
Or this post covers a bunch of deserialization options.

How can I view string content being written by XMLWriter to a Stream/MemoryStream?

How can I view the content I write with XMLWriter object to a MemoryStream object?
Note that the MemoryStreamobject isn't a member field of the class and I don't have access to it in the relevant method in which I write to it with XMLWriter.
I thought I will be able to look at the MemoryStream by the XMLWriter object itself, which is linked to the MemoryStream it writes to, but It seems that who wrote XMLWriter didn't think about that option. :\
Thanks
I assume you would like to get string value from your MemoryStream object?
Try this:
memoryStream.Position = 0;
var sr = new StreamReader(memoryStream);
var myStr = sr.ReadToEnd();
Console.WriteLine(myStr);

XmlSerializer Converts newlines

I'm trying to serialize an object to memory, pass it to another process as a string, and deserialize it.
I've discovered that the XML Serialization process strips the \r off of the newlines for strings in the object.
byte[] b;
// serialize to memory.
using (MemoryStream ms = new MemoryStream())
{
XmlSerializer xml = new XmlSerializer(this.GetType());
xml.Serialize(ms, this);
b = ms.GetBuffer();
}
// I can now send the bytes to my process.
Process(b);
// On the other end, I use:
using (MemoryStream ms = new MemoryStream(b))
{
XmlSerializer xml = new XmlSerializer(this.GetType());
clone = (myObject)xml.Deserialize(ms);
}
How do I serialize an object without serializing it to disk just like this, but without mangling the newlines in the strings?
The strings should be wrapped in CDATA sections to preserve the newlines.
The answer came from anther SO post, but I'm reposting it here because I had to tweak it a little.
I had to create a new class to manage XML read/write to memory stream. Here it is:
public class SafeXmlSerializer : XmlSerializer
{
public SafeXmlSerializer(Type type) : base(type) { }
public new void Serialize(StreamWriter stream, object o)
{
XmlWriterSettings ws = new XmlWriterSettings();
ws.NewLineHandling = NewLineHandling.Entitize;
using (XmlWriter xmlWriter = XmlWriter.Create(stream, ws))
{
base.Serialize(xmlWriter, o);
}
}
}
Since it is built on top of XmlSerializer, it should behave exactly as expected. It's just that when I serialize with a StreamWriter, I will use the "safe" version of the serialization, thus saving myself the headache.
I hope this helps someone else.

Categories