0

I have a class with four properties and the last two may be null. If they are, I don't want to return them in the result set.

public class Foo
{
    public string prop1 { get; set; }
    public string prop2 { get; set; }
    public string prop3 { get; set; }
    public string prop4 { get; set; }
}

And this Azure function:

[FunctionName("Func1")]
public Task<IActionResult> GetFunc1([HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = null)] HttpRequest req)
{
    Foo foo = new foo();
    foo.prop1 = "string1";
    foo.prop2 = "string2";  // prop3 and 4 are undefined

    var result = foo.GetType().GetProperties()
                    .Where(x => x.PropertyType == typeof(string))   // check type
                    .Select(x => (x.Name + ": " + (string)x.GetValue(foo)))   // get values
                    .Where(value => !string.IsNullOrEmpty(value));    // filter results

    return Task.FromResult<IActionResult>(new JsonResult(result)
    { 
        StatusCode = 200
    });
}

this returns

{
    "prop1: string1",
    "prop2: string2",
    "prop3: ",
    "prop4: "
}

and it's not in json format (where each property and value should have double quotes around it. The null properties are also getting returned and shouldn't be. If I modify the result calculation to:

var result = foo.GetType().GetProperties()
.Where(x => x.PropertyType == typeof(string))   // check type
.Select(x => (string) x.GetValue(foo))   // get values
.Where(value => !string.IsNullOrEmpty(value)  // filter result

I get only the values without the property names like

{
    "string1",
    "string2"
}

How do I format the result query to return the non-null properties and values in json format like this:

{
    "prop1": "string1",
    "prop2": "string2"
}

EDIT: Here's the solution as proposed by @Matt and @rené-carannante in the duplicate question:

First, update the class with attributes:

public class Foo
{
    public string prop1 { get; set; }
    public string prop2 { get; set; }

    [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
    public string prop3 { get; set; }

    [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
    public string prop4 { get; set; }
}

Second, clean up my function by just letting Newtonsoft.Json do the work of automatically removing the null properties for us:

[FunctionName("Func1")]
public Task<IActionResult> GetFunc1([HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = null)] HttpRequest req)
{
    Foo foo = new foo();
    foo.prop1 = "string1";
    foo.prop2 = "string2";  // prop3 and 4 are undefined

    return Task.FromResult<IActionResult>(new JsonResult(foo)
    { 
        StatusCode = 200
    });
}

It now automatically returns the proper json:

{
    "prop1": "string1",
    "prop2": "string2"
}

instead of the default without the nullValueHandling in place:

{
    "prop1": "string1",
    "prop2": "string2",
    "prop3": null,
    "prop4": null
}
  • What if you have a where like this before the select: .Where(x => (x.PropertyType == typeof(string)) && !string.IsNullOrEmpty(x.GetValue(foo))) ? – Lajos Arpad Sep 12 '19 at 12:46
  • Yes, thanks @Matt and René - I think I vaguely remembered something about the NullValueHandling=NullValueHandling.Ignore attribute, but didn't think to apply it here. That worked perfectly to remove the nulls automatically. Thanks again for your expertise! I'd upvote your comments but don't have enough of a reputation/points to even do that... –  Sep 12 '19 at 14:04
  • I suggest posting your solution here and marking it as answer so the question can be closed and others can see the solution :) – Matt Sep 12 '19 at 14:11
  • @LajosArpad - if I use that syntax, it complains about the second part of the code you're proposing to add with the error `Argument 1: cannot convert from 'object' to 'string'`. –  Sep 12 '19 at 14:21
  • I see. We could fix that, but there is no point to do it, since the issue was already solved. – Lajos Arpad Sep 12 '19 at 14:46
  • Your suggestion was helpful in helping me to understand Linq better, and I appreciate that... –  Sep 12 '19 at 14:49

1 Answers1

-1

You should not build yourself your serialization but instead use a specialized Library.

The most used is Newtonsoft that is very easy to use. You have a Nuggets.

https://www.newtonsoft.com/json

You will find a lot of samples here:

https://www.newtonsoft.com/json/help/html/SerializeObject.htm