Hook OData's $metadata response and convert it from XML to JSON - c#

The answer of Get OData $metadata in JSON format states that OData cannot return the metadata as JSON by default.
But is it possible then to capture or hook its response for the $metadata URL, and then convert it on the fly to JSON before sending it to the client?
I imagine pseudocode like this:
[HttpGet]
[ODataRoute("$metadata")]
public string GetMetadataAsJson()
{
string xml = GetOdataMetadataAsXML();
string json = ConvertToJson(xml);
return json;
}
I don't know how to implement it correctly, though, in particular I'm not sure how to get the standard OData response as a string, and how to hook the $metadata URL.

Newtonsoft supports the Json part checkout https://www.newtonsoft.com/json/help/html/ConvertXmlToJson.htm
So the actual solution for the Json Part would be quite simple, as soon as you have your XML
[HttpGet]
[ODataRoute("$metadata")]
public string GetMetadataAsJson()
{
string xml = GetOdataMetadataAsXML();
XmlDocument doc = new XmlDocument();
doc.LoadXml(xml);
string json = JsonConvert.SerializeXmlNode(doc);
return json;
}
Also you should probably first check if e.g. a format query is set for example with this code
[HttpGet]
[ODataRoute("$metadata")]
public string GetMetadataAsJson([FromQuery(Name="Format")]string format)
{
string metaResult = GetOdataMetadataAsXML();
if(format.Equals("json",StringComparison.OrdinalIgnoreCase))
{
XmlDocument metaDoc = new XmlDocument();
doc.LoadXml(metaResult);
metaResult = JsonConvert.SerializeXmlNode(doc);
}
return metaResult;
}

Related

How to generate Xml or Json Output Format from Xml raw string?

I'm trying to make use of FormatFilter to generate 'json' or 'xml' controller response output.
The problem is that my starting point it's a random (well-formed) xml string.
I'm using DotNet Core 2.2 and this is what I have right now in controller:
[HttpGet("values.{format}"), FormatFilter]
public ActionResult TestObjectOutput()
{
string xml = DynamicXmlRawString();
XDocument doc = XDocument.Parse(xml);
string json = JsonConvert.SerializeXNode(doc);
dynamic obj = JsonConvert.DeserializeObject<ExpandoObject>(json);
return Ok(obj);
}
public static string DynamicXmlRawString()
{
return $#"<Result><DateTime>{DateTime.Now}</DateTime><User><Someone>12345678</Someone></User></Result>";
}
The output response for json is coming as expected.
$ curl -i -X GET http://0.0.0.0:5000/api/values/object.json
{"Result":{"DateTime":"27/04/2019 16:31:27","User":{"Someone":"12345678"}}}
The response for xml returns HTTP/1.1 406 Not Acceptable
curl -i -X GET http://0.0.0.0:5000/api/values/object.xml
Server error:
An error occurred while trying to create an XmlSerializer for the type 'System.Dynamic.ExpandoObject'.
Expected result:
<Result><DateTime>27/04/2019 16:40:05</DateTime><User><Someone>12345678</Someone></User></Result>
Any idea how to solve this?
Thanks
Seems like I was overthinking...problem solved.
[HttpGet("values.{format}"), FormatFilter]
public ActionResult TestObjectOutput()
{
string xml = DynamicXmlRawString();
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(xml);
return Ok(xmlDoc);
}
public static string DynamicXmlRawString()
{
return $#"<Result><DateTime>{DateTime.Now}</DateTime><User><Someone>12345678</Someone></User></Result>";
}

send list<xmldocument> to wcf, how to do it?

I'm trying to send List to wcf.
i want to send it as json, is there a way ?
when I'm trying to serialize, i get empty string, why ?
public string ImportXml(List<XmlDocument> docs,string token)
{
Account user = GetCurrentUser(token);
string url = string.Format("{0}ImportXml/{1}", ServiceUrl, user.Unumber);
string contentType = "text/json";
x.Serialize(Console.Out, docs);
string jsonReq = _serializer.Serialize(docs);
bool response = false;
HttpRequestHandler handler = new HttpRequestHandler();
string result = handler.HttpPostWithToken(url, jsonReq, contentType, token);
return result ;
}
Each element of the collection docs before sending into WCF is must be serialized into the JSON for example in this way:
string jsonText = JsonConvert.SerializeXmlNode(doc);
where doc is XmlDocument.
Or for Javascript in this way: Converting between XML and JSON
After you get collection of XmlDocument into WCF method try convert each element of entrance collection:
var documents = new List<XmlDocument>();
foreach (var doc in docs)
{
XmlDocument xmlDoc = JsonConvert.DeserializeXmlNode(doc);
documents.Add(xmlDoc);
}
finnally i got list of strings with xml in it.
it is much better, because that way we can work with anyone, and not only C#.
and i moved to newtonsoft instead JSS.
List<string>

Return json without binding it to object using web client

I want to simply return a JsonResult in C# from an online API service (iTunes). What I am wanting to do is just go out get the data in JSON format and return that exact data in the same JSON format so I can play with it in javascript.
Here is what I have:
public JsonResult Index()
{
using (var client = new WebClient())
{
var json = client.DownloadString("https://itunes.apple.com/lookup?id=909253");
return json;
}
}
I am noticing I can't return the json because it is now a string. I don't want to bind this to a model!!! I just want to return a JSON object exactly how I got it.
Change your method signature to return a string instead of a JsonResult object…
public string Index()
{
using (var client = new WebClient())
{
return client.DownloadString("https://itunes.apple.com/lookup?id=909253");
}
}
Already given answer is ok to get json in javascript.. javasript will treat this string same as if your return json object..
However if you have to get a json object from string in c# anyway then check the accepted answer here
Parse JSON String to JSON Object in C#.NET

Deserializing the object inside an http post

Hi I am trying to deserialize an Object from a HttpPost method call inside an authorize attribute.I am using ASP.NET Web Api Framework.
Here is my code:
public override void OnAuthorization(HttpActionContext actionContext)
{
var rezult = DeserializeStream<EvaluationFormDataContract>(actionContext.Request.Content.ReadAsStreamAsync().Result);
}
private T DeserializeStream<T>(Stream stream)
{
var binaryFormatter = new BinaryFormatter();
var rez = binaryFormatter.Deserialize(stream);
var t = (T)binaryFormatter.Deserialize(stream);
return t;
}
When this code gets executed I get this exception when the binaryFormatter tryes to deserialize it:
The input stream is not a valid binary format. The starting contents (in bytes) are: 73-74-75-64-65-6E-74-41-73-73-69-67-6E-6D-65-6E-74 ...
What am I doing wrong?
You are trying to use BinaryFormatter to binary deserialize data which was not binary serialized. From data you sent I see that hex code represents a string.
73-74-75-64-65-6E-74-41-73-73-69-67-6E-6D-65-6E-74 decoded is studentAssignment
This leads me to believe you are doing a simple AJAX call and sending JSON data to WebAPI service.
You need to deserialize the stream using JSON.
Read request content as string
If content is JSON, deserialize it using JSON.NET
var json = actionContext.Request.Content.ReadAsStringAsync().Result;
var m = JsonConvert.DeserializeObject<EvaluationFormDataContract>(json);
If response is not JSON, but form data you can parse it like a query string.
var stringData = actionContext.Request.Content.ReadAsStringAsync().Result;
NameValueCollection data = HttpUtility.ParseQueryString(stringData);
string personId = data["personId"];

Converting JSON to XML

I trying to convert JSON output into XML. Unfortunately I get this error:
JSON root object has multiple properties. The root object must have a single property in order to create a valid XML document. Consider specifing a DeserializeRootElementName.
This is what I up to now created.
string url = string.Format("https://graph.facebook.com/{0}?fields=posts.fields(message)&access_token={1}", user_name, access_token);
HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
{
StreamReader reader = new StreamReader(response.GetResponseStream());
jsonOutput = reader.ReadToEnd();
Console.WriteLine("THIS IS JSON OUTPUT: " + jsonOutput);
}
XmlDocument doc = (XmlDocument)JsonConvert.DeserializeXmlNode(jsonOutput);
Console.WriteLine(doc);
And this is my JSON output:
{"id":"108013515952807","posts":{"data":[{"id":"108013515952807_470186843068804","created_time":"2013-05-14T20:43:28+0000"},{"message":"TEKST","id":"108013515952807_470178529736302","created_time":"2013-05-14T20:22:07+0000"}
How can I solve this problem?
Despite the fact your JSON provided in the question is not complete, you have multiple properties at the top level as indicated by the exception. You have to define the root for it to get valid XML:
var doc = JsonConvert.DeserializeXmlNode(jsonOutput, "root");
EDIT: In order to print out your XML with indentation you can use XDocument class from System.Xml.Linq namespace: XDocument.Parse(doc.InnerXml).
I thought it's worth linking to the Documentation for turning xml to json and the other way around.
The guys are right..
// To convert an XML node contained in string xml into a JSON string
XmlDocument doc = new XmlDocument();
doc.LoadXml(xml);
string jsonText = JsonConvert.SerializeXmlNode(doc);
// To convert JSON text contained in string json into an XML node
XmlDocument doc = (XmlDocument)JsonConvert.DeserializeXmlNode(json);
You can do JSON-to-XML also by using the .NET Framework (System.Runtime.Serialization.Json):
private static XDocument JsonToXml(string jsonString)
{
using (var stream = new MemoryStream(Encoding.ASCII.GetBytes(jsonString)))
{
var quotas = new XmlDictionaryReaderQuotas();
return XDocument.Load(JsonReaderWriterFactory.CreateJsonReader(stream, quotas));
}
}
DeserializeXmlNode returns XDcument.
If needed XNode use FirstNode.
//string jsonOutput="{"id":"108013515952807","posts":{"data":[{"id":"108013515952807_470186843068804","created_time":"2013-05-14T20:43:28+0000"},{"message":"TEKST","id":"108013515952807_470178529736302","created_time":"2013-05-14T20:22:07+0000"}";
var myelement= JsonConvert.DeserializeXmlNode(jsonOutput, "myelement").FirstNode;
Your shared JSON is invalid please go through http://jsonformatter.curiousconcept.com/ and validate your JSON first.
Yourt JSON should look like:
{
"id":"108013515952807",
"posts":{
"data":[
{
"id":"108013515952807_470186843068804",
"created_time":"2013-05-14T20:43:28+0000"
},
{
"message":"TEKST",
"id":"108013515952807_470178529736302",
"created_time":"2013-05-14T20:22:07+0000"
}
]
}
}
Adding on #jwaliszko's answer, converting json to XDocument:
XDocument xml = JsonConvert.DeserializeXNode(json);

Categories

Resources