Make an XML element mandatory - asp.net

Here I am currently working on a program that will serialize an XML file asp.net object. My problem is that I can not find the attribute that makes it mandatory to have a tag in the XML file.
You will find below the definition of my object.
[System.SerializableAttribute()]
public class EchangeIdentification
{
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute("agrement")]
public string Agrement{ get; set; }
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute("cvi")]
public string NumeroCvi { get; set; }
/// <remarks/>
[Required]
[XmlElement("siret")]
public string Siret { get; set; }
}

As far as I know, there is no way to declaratively force elements and attributes to be required using the XmlSerializer. C# object properties that can be null are always optional.
A few observations
[Serializable] is not used by the XML Serializer.
There is no way to make it required using the XML Serializer, but if you don't have to use XmlSerializer? DataContractSerializer provides the following option:
[DataMember(IsRequired = true)]
You don't need the "Attribute" name in the code, your code could look like this
[Serializable]
public class EchangeIdentification
{
[XmlElement("agrement")]
public string Agrement{ get; set; }
[XmlElement("cvi")]
public string NumeroCvi { get; set; }
[XmlElement("siret")]
public string Siret { get; set; }
}

Define "serialize an XML file asp.net object" and "makes it mandatory to have a tag in the XML". It all depends on how you're using this class.
Are you using it as a deserialization container, into which you will deserialize XML you receive? Then create an XSD schema, and validate the incoming XML before (or rather during) serialization. See Validating an XML against referenced XSD in C#.
On the other hand, if the user of this code is assigning properties of an instance of this class at runtime, and you serialize it through XmlSerializer, you could validate the output after serializing. See the linked question above, and Can I fail to deserialize with XmlSerializer in C# if an element is not found?.
Alternatively, you could implement serialization callbacks and create a validation method that throws an exception if [Required] properties have the default value for their type.
I'd go with the XSD route either way.

Related

How to return serialized JSON string, without further serialization from ASP.Net Core API

This question is similar to Return "raw" json in ASP.NET Core 2.0 Web Api but slightly more complicated.
I have a mixed content, some class like:
public class ResponseModel
{
public Guid Id { get; set; }
public DateTime TimesStamp { get; set; }
// this is actually JSON serialized data,
// which the function just passes through and doesn't need to understand
public string Data { get; set; }
}
Currently, a response would contain the Id and TimeStamp serialized correctly and Data would just be a string which would need to be deserialized one more time.
I'd instead want Data to be just pointing to the "Raw" json string, which I set it to, without further escaping it.
We don't make use of content negotiation, we only support JSON request and response, so this would be fine.
I know that I could deserialize the json string into a dynamic object and that would work, but why should the string be deserialized just to be serialized again?
So what I would want is something like
public class ResponseModel
{
public Guid Id { get; set; }
public DateTime TimesStamp { get; set; }
public object Data { get; set; }
}
but without the need to spend unnecessary time to deserialize and again serialize the content of the json string.
Not possible. If it's a string, you know it's JSON, but the serializer has no way of knowing that. However, even if it could somehow determine that it's a JSON string, it would still need to internally deserialize it so it could work it into the rest of the object, before serializing the whole thing - effectively no different than doing it yourself.

How can I serialize data to XML without .xsd schema?

I am writing an ASP.NET MVC (5) application in which I need to do some custom XML serialization. Before I go on, I should mention that I wasn't exactly sure if this question belongs here or on another forum. If this question would be better suited somewhere else, please let me know. I'll gladly move it.
Software overview:
I have a view that has a form for the user to fill out. When the user fills out the required fields and clicks the submit button, the information in the form should be serialized to XML (based on certain XML requirements), and posted to a URL. That's pretty simple for some, I'm sure. I have very little experience doing this sort of thing in ASP.NET MVC.
I don't possess the .xsd document that contains the XML schema. I have a document that contains the XML specifics (a Word document), but the actual .xsd document is not available to me. I am not sure how to serialize the data so that the XML turns out the way it is supposed to.
I have the following Model:
public class BookingRequest
{
public string billTo { get; set; }
public string bookingStatus { get; set; }
public string partNote { get; set; }
public int height { get; set; }
}
Note that this is an abbreviated version; there are WAY more fields in this class. Anyway, I need the height field to look like this when it is serialized to XML:
<HeightOf>15</HeightOf>
I also need all of the elements in the XML to adhere to this schema (where all of the fields in the form I mentioned fall under the <BookingRequest> tag):
<Data>
<Header>
<UserId/>
<Password/>
</Header>
<BookingRequest>
..
..
</BookingRequest>
</Data>
Can I do this without the schema?
Any help is greatly appreciated.
You don't need the xsd, as long as you know how is going to be the desired structure.
First, you need to decorate your class with the [Serializable] attribute. Then, you can use the attributes in System.Xml.Serialization namespace to control the result. For example, in case of height property, it can be achieve like this:
[Serializable]
public class BookingRequest
{
public string billTo { get; set; }
public string bookingStatus { get; set; }
public string partNote { get; set; }
[XmlElement(ElementName = "HeightOf")]
public int height { get; set; }
}
See this for further details:
https://learn.microsoft.com/en-us/dotnet/standard/serialization/controlling-xml-serialization-using-attributes

Json object using WebAPI controller

I am using webapi controller.I have to pass an JSON object from Java applet to web api controller. How to write a web api controller method to accept the JSON object
public test GetPo(int id)
{
}
ASP.NET Web API uses JSON format as default format:
JSON formatting is provided by the JsonMediaTypeFormatter class. By default, JsonMediaTypeFormatter uses the Json.NET library to perform serialization. Json.NET is a third-party open source project.
what you just do is to defined your model object which map with json:
public class Model
{
public int Property1 { get; set; }
public string Property2 { get; set; }
// More properties
}
And your POST method:
public void Post(Model model)
{}

serializing/deserializing derived objects using JSON.NET without using JsonProperty?

I'm using the NewtonSoft JSON.NET library for serializing the following class where DTOBase can hold derived instances.
public class Command
{
public DTOBase CommandDTO { get; set; }
}
Per this article you need to include the JsonProperty attribute so that the derived instances get deserialized properly
public class Command
{
[JsonProperty(TypeNameHandling = TypeNameHandling.All)]
public DTOBase CommandDTO { get; set; }
}
The question is whether there is any other way besides using an attribute to get the same result? I would prefer to not be coupled to the NewtonSoft library and json serialization in particular at the class level. Is there a way to specify some settings on the Serialize/Deserialize methods of the library at all to get the same result?
The TypeNameHandling property can be set on JsonSerializerSettings when you call JsonConvert.SerializeObject(value, settings).
If you only want the name included for derived objects set TypeNameHandling to TypeNameHandling.Auto.

Deserializing JSON objects as List<type> not working with asmx service

I am having trouble deserializing my JSON string. I have a class of type person with public properties for sequence number of type int, first name, and last name. I want to pass an array of these objects in JSON format and have them deserialized as a list so I can loop through them on the server, but ASP.NET says something about not being supported to be deserialized as an array. I have validated the JSON I am producing, and it is valid. Is there something special about the JSON that ASP.NET needs to have before it can deserialize? The funny thing is if I serialize a list<person> object to JSON it looks exactly like the JSON I am producing. I must be missing something... To clarify, I'm using the ASP.NET Ajax library to deserialize. This is what I get back from the web service:
{"Message":"Type \u0027System.Collections.Generic.IDictionary`2[[System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.Object, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]\u0027 is not supported for deserialization of an array."
Actually unfortunately this doesn't seem to have anything to do with deserializing, it appears that you can't pass an array of JSON objects to an asmx web service. Am I correct? If you can't do that, is it possible to pass a collection of JSON objects to a web service and have them processed on the server with ASP.NET and C#?
Update:
OK, here is my code. Here is the person class:
public class person
{
public person()
{
//
// TODO: Add constructor logic here
//
}
public int seq
{
get;
set;
}
public string firstName
{
get;
set;
}
public string lastName
{
get;
set;
}
}
And here is my JSON string:
[{"seq":1,"firstName":"Chris","lastName":"Westbrook"},
{"seq":2,"firstName":"sayyl","lastName":"westbrook"}]
And here is the code I'm using
[WebMethod]
public void updatePeople(string json)
{
IList<person> people =
new JavaScriptSerializer().Deserialize<IList<person>>(json);
//do stuff...
}
I figured it out. I wasn't wrapping my JSON in an object like ASP.NET Ajax requires. For future viewers of this question, all JSON objects must be wrapped with a main object before being sent to the web service. The easiest way to do this is to create the object in JavaScript and use something like json2.js to stringify it. Also, if using an asmx web service, the objects must have a __type attribute to be serialized properly. An example of this might be:
var person=new object;
person.firstName="chris";
person.lastName="Westbrook";
person.seq=-1;
var data=new object;
data.p=person;
JSON.stringify(data);
This will create an object called p that will wrap a person object. This can then be linked to a parameter p in the web service. Lists of type person are made similarly, accept using an array of persons instead of just a single object. I hope this helps someone.
Could you show the JSON string you are trying to deserialize and the way you are using the Deserialize method? The following works fine:
using System;
using System.Collections.Generic;
using System.Web.Script.Serialization;
namespace Test
{
class Program
{
class Person
{
public int SequenceNumber { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
public static void Main()
{
string json = "[{\"SequenceNumber\":1,\"FirstName\":\"FN1\",\"LastName\":\"LN1\"},{\"SequenceNumber\":2,\"FirstName\":\"FN2\",\"LastName\":\"LN2\"}]";
IList<Person> persons = new JavaScriptSerializer()
.Deserialize<IList<Person>>(json);
Console.WriteLine(persons.Count);
}
}
}
Or even simpler, when you are doing the $.ajax(...) use
data:"{\"key\":"+JSON.stringify(json_array)+"}",
and then on the other side of the code, make your function use the parameter "object key"
[WebMethod]
public static return_type myfunction(object key){...}
SERVER SIDE
[WebMethod]
public void updatePeople(object json)
CLIENT SIDE
var person = "[{"seq":1,"firstName":"Chris","lastName":"Westbrook"}
,{"seq":2,"firstName":"sayyl","lastName":"westbrook"}]";
var str = "{'json':'" + JSON.stringify(person) + "'}";
I think the problem is what type you have to deserialize. You are trying to deserialize type
IList
but you should try to deserialize just
List
Since interface can not be instantiated this might is the root problem.

Resources