0

I have written a web service which can be called from a javascript. It's all working fine but i notice that more properties are being returned than i expected...

url: http://localhost/intranet/Contacts.asmx/ContactsDirectory

In short, it reads the employees from a database and adds them to a list. Note that i am only adding 5 of the 13 properties available:

    foreach (DataRow row in ResultsDataTable.Rows)
    {
        var Employee = new Employees();
        Employee.Firstname = row["FIRSTNAME"].ToString();
        Employee.Surname = row["SURNAME"].ToString();
        Employee.PostTitle = row["POST"].ToString();
        Employee.Department = row["DEPTARTMENT"].ToString();
        Employee.Email = row["EMAIL"].ToString();
        employees.Add(Employee);
    }

My Employees class with the 13 properties:

public class Employees
{
    public string PersonRef;
    public string Firstname;
    public string Surname;
    public string PrefName;
    public string Telephone;
    public string PostRef;
    public string PostTitle;
    public string Department;
    public string Section;
    public string Location;
    public string Email;
    public string Manager;
    public string ManagersEmail;
}

My AJAX request:

xhr = $.ajax({
    type: 'POST',
    url: './intranet/Contacts.asmx/ContactsDirectory',
    data: JSON.stringify({ Name: "Scott" }),
    contentType: 'application/json; charset=utf-8',
    dataType: 'json'
});

You can see from the response below that the Properties Manager and ManagersEmail are being returned, but they weren't in my list! How do i prevent this? Note: i can't remove any of the properties from my class as other web services use these properties.

enter image description here

Scott
  • 1,280
  • 4
  • 20
  • 35
  • 2
    The browser returns `XML`, which I'd guess doesn't display `NULL` values. I'd expect the web service to return all properties of the class, `NULL` or not. But perhaps someone else has a more definite answer. – Tyler Roper Mar 17 '17 at 13:40
  • I'm not really familiar with C#, but i think the problem is in serialization. What you see in your browser is `xml`, but jquery is receiving `json`. – ScheRas Mar 17 '17 at 13:42
  • json encodes always include empty attributes, jQuery or not. Either the webservice is not including the empty attributes or the browser is not rendering them – user3154108 Mar 17 '17 at 13:44
  • @ScheRas seems to be on the right track. My initial assumption, after a bit of research, seems to be correct. **Without an `xsi:nil="true"` property on the XML object, it won't return `NULL` values.** Consider checking out [this question](http://stackoverflow.com/questions/774192/what-is-the-correct-way-to-represent-null-xml-elements) for a bit more information. – Tyler Roper Mar 17 '17 at 13:44
  • @Santi I can confirm that viewing the webservice in the browser does display any properties that have null values, they are self closed like: – Scott Mar 17 '17 at 13:48
  • 1
    @Scott Correct, so as you can see, the return always includes every property, NULL or not. If you really don't want these to come over, you might need to create a string or object with only the properties that are not NULL, and return that. With all of this in mind, I'd suggest editing the question to reflect what you're really asking: "How can I pass an object to AJAX *without* NULL properties", or something. The XML stuff is now a bit misleading, you may get answers focused on that instead of your real issue. – Tyler Roper Mar 17 '17 at 13:51
  • did you consider any answer useful and/or acceptable? – Vladislav Oct 16 '18 at 21:18

5 Answers5

0

The difference comes from the fact that you "query" the data in different formats. JSON always displays all properties of the object, because you defined them - they are part of the object no matter the value. The fact that you did not set them, does not change the object definition... thankfully :)

With XML, however, we have a different standard. By default the .NET serializer (in accordance to the XML specification) does not include properties that have NULL values, you should explicitly define this by using the appropriate XML attribute: https://msdn.microsoft.com/en-us/library/system.xml.serialization.xmlelementattribute.isnullable(VS.85).aspx

Furthermore, you can refer to the XML specification about showing elements with NULL values here: https://www.w3.org/TR/xmlschema-1/#xsi_nil

Vladislav
  • 2,772
  • 1
  • 23
  • 42
0

The difference comes because the browser request is asking for a different response format than the ajax request. However its actually more subtle than that. It has to do with the serialization settings being functionally different between the two serializers.

The JSON serializer setting is setup to include null properties, if you change its setup to omit null properties it will not output those fields that are null.

You can force the xml serializer to include null properties with the use of an attribute on the property definition.

anyway, SO has many answers on how to have the default json serializer omit nulls. here is one example

Community
  • 1
  • 1
danatcofo
  • 703
  • 8
  • 18
0

If you serialize an object to return via json then it will take all the properties of the object even if they are null. This is expected behavior and there is actually a valid reason for that(think of the situations where you would want to know a property is null.) if it is truly an issue that you have the extra properties than create a view model that only has the properties you want and select your data into that instead OR refactor your base classes to handle.

Travis Acton
  • 4,292
  • 2
  • 18
  • 30
0

Add the [ScriptIgnore] attribute to any properties that you DON'T want to be serialized into JSON.

using System.Web.Script.Serialization;

public class Employees
{
    public string PersonRef;
    public string Firstname;
    public string Surname;
    public string PrefName;
    public string Telephone;
    public string PostRef;
    public string PostTitle;
    public string Department;
    public string Section;
    public string Location;
    public string Email;
    [ScriptIgnore]
    public string Manager;
    [ScriptIgnore]
    public string ManagersEmail;
}
Joe Irby
  • 649
  • 6
  • 7
0

If you could switch your service to WCF, you can omit NULL values by using EmitDefaultValue

[DataMember(EmitDefaultValue = false)]
public string Manager{ get; set; }

[DataMember(EmitDefaultValue = false)]
public string ManagerEmail{ get; set; }
TTCG
  • 8,805
  • 31
  • 93
  • 141