Avoid serialize propertie/field that is not set? - c#

I have generated a WCF proxy from a WSDL file and are having problems with a property/field.
The propertie is of a complex type(class) and is decorated with the following attribute in the generated code.
XmlElementAttribute(IsNullable=true)
When the propertie is not set to an object the serializer will still generate it in the XML like this
<OpDDoctorInfo xsi:nil="true" />
I need it to not be generated at all.
I really dont like to change in a generated proxy file but I dont seem to have any other choise?
From this link I can see that if there is a default value and the value that is set is the same then the default behavior will be to exclude it from the xml so why have it been generetad with a attribute like this?
Edit: some thinks that this is a dubblicate of this :
What is the correct way to represent null XML elements?
It is not, that questions asks what the correct way is to handle null. Im asking how to remove the propertie/field from the generated XML while using a generated proxy class. Maybe I have to change in the proxy generated code or is there a better way?

Related

Do not create Complex type in WSDL from C# class

I need to create a web service and generate the corresponding WSDL file.
I need to provide a list of fields related to a customer, such the name, the address and so on.
The problem is I need to keep them in the body of the WSDL without generating a complex type, but I would like to wrap all these fields in the Customer class.
Is there a way not to generate the complex type from a class, and tell to just consider its variables? Googling around I always found the opposite question!
Thanks in advance.
EDIT: To explain it a little bit better, my WSDL should have a similar snippet:
<pos:NAME>?</pos:NAME>
<pos:SURNAME>?</pos:SURNAME>
<pos:ADDRESS>?</pos:ADDRESS>
<pos:OTHER_DATA>?</pos:OTHER_DATA>
<pos:OTHER_DATA2>?</pos:OTHER_DATA2>
<pos:OTHER_DATA3>?</pos:OTHER_DATA3>
I would like to create a "Customer" class in my code for better code management, without the risk of generating something like:
<pos:CUSTOMER>
<pos:NAME>?</pos:NAME>
<pos:SURNAME>?</pos:SURNAME>
<pos:ADDRESS>?</pos:ADDRESS>
</pos_CUSTOMER>
<pos:OTHER_DATA>?</pos:OTHER_DATA>
<pos:OTHER_DATA2>?</pos:OTHER_DATA2>
<pos:OTHER_DATA3>?</pos:OTHER_DATA3>

how to set XmlAttribute as IsRequired?

Can we have a required XmlAttribute that does not allow null value?
I want to have something like IsRequired = true in XmlAttribute. Can it be done? I know that there is a 'use="required"' for XmlAttribute, but we can't set its value, can we? Is there any trick to serve this purpose?
I'm still a little confused by what you're trying to do, so i'm assuming that you wish to validate your input xml before attempting to use it in your webservice. In your case your XML needs to have a specific attribute.
To do something like that I typically create an XSD against the XML that should be received and use that to validate it against the XML. The XSD will contain the details that the XML must contain a certain node / attribute. You can use visual studio XSD editor to configure these items.
This topic should help you with the validation code once you're XSD is created:
Validating an XML against referenced XSD in C#

XmlSerializer.Deserialize - ignore unnecessary elements?

I've got an XSD schema which I've generated a class for using xsd.exe, and I'm trying to use XmlSerializer.Deserialize to create an instance of that class from an XML file that is supposed to conform to the XSD schema. Unfortunately the XML file has some extra elements that the schema is not expecting, which causes a System.InvalidOperationException to be thrown from Deserialize.
I've tried adding <xs:any> elements to my schema but this doesn't seem to make any difference.
My question is: is there any way to get XmlSerializer.Deserialize to ignore these extra elements?
I usually add extra properties or fields to all entity classes to pick up extra elements and attributes, looking something like the code below:
[XmlAnyAttribute]
public XmlAttribute[] AnyAttributes;
[XmlAnyElement]
public XmlElement[] AnyElements;
Depending on the complexity of your generated code, you may not find hand-inserting this code on every entity appealing. Perhaps only-slightly-less-tedious is defining these attributes in a base class and ensuring all entities inherit the base.
To give fair attribution, I was first introduced to this pattern when reading the source code for DasBlog.
I don't think there is an option to do this. You either have to fix the schema or manually modify the code generated by xsd.exe to allow the XML to be deserialized. You can also try to open the XML document + schema in Visual Studio or any other XML editor with schema support to either fix the schema or the XML document.

Custom XML Serialization, how to write custom root element?

I'm probably just doing this wrong, i know.
I'm using custom serialization and when the xml is generated it's putting the class name as the root element
Example:
<MyClassName>
<MyIntendedRootNode>
<ObjectType>
<Property1/>
<Property2/>
...
I'm invoking the serialization by calling xmlserializer.Serialize(writer,Me) so I'm sure that has something to do with it.
I've tried putting XMLRoot onto the class, but I think as vb is compiling this partial class with its aspx page, it's either overwriting this property or ignoring it entirely.
Ideally I'd like to just tell it to either throw away everything it has and use a different root element.
Anybody else do this except me?
Thanks
You can use either IXmlSerializable or use the XML attributes. I use XmlSerializer passing the root in the constructor.
var MemoryStream ms;
var customRoot = dataObject as XmlRootAttribute;
var xml = new XmlSerializer(dataObject.GetType(), customRoot);
xml.Serialize(ms, dataObject);
In ASP.NET, the actual class that is loaded is a generated class that inherits from your class. (It turns out--surprisingly--that this generated code is actually separate from the additional generated code that is combined with your code using the partial class technique. The generated class has the same name as the class you are working on, but it is in a different namespace.) Since XmlRoot is not an inherited attribute, the XmlSerializer does not see it.
I don't think there is any solution (other than modify the document after you have generated it).
Are you trying to serialize a codebehind file?
I would suggest writing a model to contain the data that needs to be saved, and then serializing that instead. Then use the appropriate XMLWriter attributes to make sure your root element is correctly named.
Or you could implement IXmlSerializable and have full control over your Xml but its a bit of extra effort just to change a root element name.
You can create a wrapper class and give that wrapper class with the name that you wish to be shown in the xml root.

Is it possible to set a default value when deserializing xml in C# (.NET 3.5)?

I've got a little problem that's slightly frustrating. Is it possible to set a default value when deserializing xml in C# (.NET 3.5)? Basically I'm trying to deserialize some xml that is not under my control and one element looks like this:
<assignee-id type="integer">38628</assignee-id>
it can also look like this:
<assignee-id type="integer" nil="true"></assignee-id>
Now, in my class I have the following property that should receive the data:
[XmlElementAttribute("assignee-id")]
public int AssigneeId { get; set; }
This works fine for the first xml element example, but the second fails. I've tried changing the property type to be int? but this doesn't help. I'll need to serialize it back to that same xml format at some point too, but I'm trying to use the built in serialization support without having to resort to rolling my own.
Does anyone have experience with this kind of problem?
It looks like your source XML is using xsi:type and xsi:nil, but not prefixing them with a namespace.
What you could do is process these with XSLT to turn this:
<assignees>
<assignee>
<assignee-id type="integer">123456</assignee-id>
</assignee>
<assignee>
<assignee-id type="integer" nil="true"></assignee-id>
</assignee>
</assignees>
into this:
<assignees xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<assignee>
<assignee-id xsi:type="integer">123456</assignee-id>
</assignee>
<assignee>
<assignee-id xsi:type="integer" xsi:nil="true" />
</assignee>
</assignees>
This would then be handled correctly by the XmlSerializer without needing any custom code. The XSLT for this is rather trivial, and a fun exercise. Start with one of the many "copy" XSLT samples and simply add a template for the "type" and "nil" attributes to ouput a namespaced attribute.
If you prefer you could load your XML document into memory and change the attributes but this is not a good idea as the XSLT engine is tuned for performance and can process quite large files without loading them entirely into memory.
You might want to take a look at the OnDeserializedAttribute,OnSerializingAttribute, OnSerializedAttribute, and OnDeserializingAttribute to add custom logic to the serialization process
XmlSerializer uses xsi:nil - so I expect you'd need to do custom IXmlSerializable serialization for this. Sorry.

Categories

Resources