Web-api: property names for Xml and Json - c#

Hej, I have a web-api controller (written in c#) which returns either xml or json (as desired) according to the request. Now I have a requirement that the names of the properties in the returned objects are different, depending on whether it is Json or Xml which is bring returned. Is this possible?
For example, method "GetAddress" returns an "Address" object, with properties like "StreetName", "HouseNumber", "ZipCode"...
Now I want property names for Json like "Street" (without "Name" at all), and for Xml like "street_name", and similar differences for other properties.
Thanks,
Peter

found out I can use 2 attributes on my properties: one to name them for Json, and one to name them for Xml. For example:
[DataMember(Name = "street_name")]
[JsonProperty(PropertyName = "Street")]
public string StreetName{ get; set; }
(and also a [DataContract] attribute on the class itself).

Related

How to tell MessageQueue.SendMessageConnection how to "XMLize" the object to be sent?

I'm working in C# with a System.Messaging.MessageQueue.SendMessageConnection for sending an object, containing some parameters, something like:
_sendQueue.Send(myObject, ...);
My myObject is an object, containing some attributes, like Field1.
I'm checking how my messages get sent, using:
Computer Management
Services and Applications
Message Queuing
Private Queues
open the right queue, and in the "queue messages", right-click and check "Properties", "Body".
There I see tags like:
<Field1>content_Field1</Field1>
Instead of this, I would like to see something like:
<F1>content_Field1</F1>
Is there an easy mapping between the attributes in my object and the XML tags I would like to be used?
Thanks in advance
That's actually quite easy to do. Check out Control XML serialization using attributes :
By default, an XML element name is determined by the class or member name. In a simple class named Book, a field named ISBN will produce an XML element tag , as shown in the following example.
public class Book
{
public string ISBN;
}
// When an instance of the Book class is serialized, it might
// produce this XML:
// <ISBN>1234567890</ISBN>.
This default behavior can be changed if you want to give the element a new name. The following code shows how an attribute enables this by setting the ElementName property of a XmlElementAttribute.
public class TaxRates {
[XmlElement(ElementName = "TaxRate")]
public decimal ReturnTaxRate;
}
- Microsoft article as of 2017-03-30, various authors (emphasis by me)
The whole article is about a ~6minutes read and I really recommend it.

How to find and replace values in nested JSON dynamically

I have a service call that accepts the following model:
public class ServiceModel {
public DataModel dModel {get; set;}
public JObject schema {get; set;}
}
The DataModel is responsible for holding data that will be used to populate user defined schema (see below).
The schema is a user defined (at runtime) dynamic json structure that contains tokenized values like this. Being that it's user defined, it can be deeply nested.
{
"id": "<tokenized_id>",
"hero":{
"heroName": "<tokenized_heroName>",
"heroType": "<tokenized_heroType>",
"heroSkill": "<tokenized_heroSkill>",
"heroArmor": {
"armor_id": "<tokenized_armorId>",
...
}
}
}
What I want to do is pull data from the DataModel and replace the corresponding tokenized value with it. The tricky part comes from the possibility of deeply nested objects
My first idea is to just flatten the schema into a string and doing a Find/Replace on the entire string but I'm curious if there's a more elegant way.
There's the option of working with JObjects or even Dictionary but neither provide a nice way to access nested objects. I believe I would need to use recursion which could get ugly.
Are there betters ways to accomplish this?

Is there an equivalent to JsonSerializerSettings.MissingMemberHandling for XML serialization during Web API request handling?

I'm working on an ASP.NET Web API that allows XML and JSON formats for its resources. The resource model type for one of my Web API services has a property that users would not send. But I have to set it in response that I send back.
For example, there is a POST request where users would like to save a new item to database. And my service responds with the same resource model and an additional property indicating it is saved.
I have added this additional property to my resource model. When I test it in Fiddler passing an XML request, it is complaining with a HTTP400 saying the new property is missing. With JSON input, it is working fine, probably due to the default JSON setting JsonSerializerSettings.MissingMemberHandling.
Do we have an equivalent property to this for XML de-serialisation?
Sample input XML:
<MyResource>
<Property1>ABC</Property1>
<Property2>DEF</Property2>
</MyResource>
Sample output XML that I intend to send:
<MyResource>
<Property1>ABC</Property1>
<Property2>DEF</Property2>
<Id>123</Id>
</MyResource>
Error looks like:
The property Id was missing
My Resource model looks like:
public string Property1 { get; set; }
public string Property2 { get; set; }
public int Id { get; set; }
Microsoft's "JSON and XML Serialization in ASP.NET Web API" page has this to say about XML serialization (under the XML Serialization heading):
If you need more control over the serialization, you can decorate the class with the DataContract attribute. When this attribute is present, the class is serialized as follows:
"Opt in" approach: Properties and fields are not serialized by default. To serialize a property or field, decorate it with the DataMember attribute
The DataMember attribute has the following property:
IsRequired
Gets or sets a value that instructs the serialization engine that the member must be present when reading or deserializing.
So, from documentation, it would appear that decorating your Id property with [DataMember(IsRequired=false)] would allow the XML Serializer to allow it to remain at its default value.
Note, though, that the default value is 0, so you'll need to check explicitly for that value as the "no value" marker. If you want to logically differentiate between an entity with ID=0 and an entity with no ID, consider changing its type to int?, so the default value would be null.

Access elements in JSON array

I use an API which returns JSON. I'm having trouble with accessing elements when they are not in an array.
My JSON looks like this:
On the JSON of 2, I can access the elements with
dataJson.Storingen.Ongepland.Storing.#elementName#
However, when I use the JSON of 1, I get the following exception:
Additional information: Newtonsoft.Json.Linq.JProperty does not contain a definition for Traject
The structure of second json is different about the first.
In second case, you should use dataJson.Storingen.Ongepland.Storing[0].#property to access the property that you want.
But if you want to roll up in your array, just to use a for
The two JSONs on that picture are not similar in architecture. The first one has a nested "Storing" object, that has several properties, but in the second case, "Storing" became an array of objects. Is it possible that your object model that you're trying to map to tries to parse this array as a single object?
If so, then I think you need to change the type of "Storing" in your model to an array. You will be able to get the elements then like this:
dataJson.Storingen.Ongepland.Storing[0].#elementName#
I know this is an old post, but I thought maybe I could just share my thoughts on this question number 1 I believe, just in case someone from the future saw this.
1st. Create two classes as such:
public Storing Test {get; set;}
public class Storing
{
public string id {set; get;}
public string Traject {set; get;}
public string Periode {set; get;}
}
2nd. In the main program, deserialize the JSON and call the object as such
TestCase list = new System.Web.Script.Serialization.JavaScriptSerializer().Deserialize<TestCase>(*your web API uri*);
Console.WriteLine ("id:{0}, Traject{1}, Periode{2}", list.Id, list.Traject, list.Periode);

What is the best way to read an xml file when there is no standard schema?

I am working on an application in which, i have to read XML files that have a different set of nodes each time, although only a certain number of nodes appear in all the files, the combination in which they appear keep on changing, the XML files are generated by another system which i cannot control, I am looking into Linq to XML and XML serialization, but i guess serialization is not a choice since it needs pre-built classes to create objects.
Example XML data
<Employee>
<PersonalInfo>
<FirstName>Vamsi</FirstName>
<LastName>Krishna</LastName>
</PersonalInfo>
<EmploymentInfo>
<Department>
<Id>101</Id>
<Position>SD</Position>
<Department>
<EmploymentInfo>
</Employee>
Another Format
<Employee>
<PersonalInfo>
<FirstName>Vamsi</FirstName>
<LastName>Krishna</LastName>
</PersonalInfo>
</Employee>
You can observe that EmploymentInfo node is completely missing in the second example, there are many number of combinations in which the XML data can be presented to the application, I have to read the XML file validate it insert into an SQL Server database through my C# code.
I'd say it depends.
If you just want to communicate with another system in a strongly-typed way, and you can expect the XML schemas to not be changing very frequently, you might be OK with XML serialization. Just encapsulate the deserialization into a separate component and write different versions of them (yes, you'll need to be able to determine the schema version that is currently used). I mean, each version would have it's own set of classes that are targeted by the serializer.
But if you really cannot infer a system out of the schemas used by the external app and need some intelligent parser, you'd better use XPath or Linq to XML or some other XML-level APIs to manually handle the XML-s.
BTW, both of your samples are pretty easy for the XMLSerializer. In the second case it will just set EmploymentInfo to null.
You could write a parser class wich ueses .Net Xpath implementation. The parser should test the child elements for specific nodes before processing the data.
Visit MSDN for the complete syntax.
Update
A little example what i would do to solve the problem. At first, some Model classes to hold some data:
public class PersonalInfo
{
public string FirstName { get; set;}
public string LastName { get; set;}
// more properties
}
public class EmployeeModel
{
// remove List<> if you always just have 1 personalinfo child element
public List<PersonalInfo> {get; set;}
public List<EmploymentInfo> {get; set;}
// more properties
}
Now your "Parser":
public class MyParser
{
// load xml string or xml file in constructor
public MyParser(string xmlSource) { .. }
public EmployeeModel GetEmployeeModel()
{
var result = new EmployeeModel();
// use what ever you want to select nodes from your xml
// and set data of result
return result;
}
}
In your productive code you can use this parser class to get a model of your xml data.

Categories

Resources