Prevent null values from being emitted in a WebAPI OData v4 service

假装没事ソ 提交于 2019-12-24 00:22:52

问题


I'm running an WebAPI OData v4 service and I don't want null values to be emitted. For example, when I request a User object, the following is returned:

"value": [
{
  "FirstName": "John",
  "LastName": "Smith",
  "EmailAddress": "john@smith.com",
  "PasswordHash": null,
  "PhoneNumber": "11234567890",
  "Website": null,
  "Id": "dac9706a-8497-404c-bb5a-ca1024cf213b"
}

Since the PasswordHash and Website fields are null, I'd like them to not be included in the output. I've tried the following lines in the application's Register block, but none of them work:

config.Formatters.JsonFormatter.SerializerSettings = new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore };
config.Formatters.JsonFormatter.SerializerSettings.DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate;
config.Formatters.JsonFormatter.SerializerSettings.NullValueHandling = NullValueHandling.Ignore;

Below is the full contents of the Register method. I'm using the Newtonsoft Json package to handle the JSON serialization.

public static void Register(HttpConfiguration config)
    {
        // Web API configuration and services
        config.SuppressDefaultHostAuthentication();
        config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));

        // Web API routes
        config.MapHttpAttributeRoutes();

        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );

        config.Routes.MapHttpRoute(
            name: "UploadComplete",
            routeTemplate: "UploadFiles/Complete",
            defaults: new { controller = "UploadFiles", action = "Complete" }
        );

        var builder = new ODataConventionModelBuilder();

        builder.EntitySet<Address>("Addresses");
        builder.EntitySet<Assignment>("Assignments");
        builder.EntitySet<Course>("Courses");
        builder.EntitySet<File>("Files");
        builder.EntitySet<UploadFile>("UploadFiles");
        builder.EntitySet<Organization>("Organizations");
        builder.EntitySet<Submission>("Submissions");
        builder.EntitySet<Term>("Terms");
        builder.EntitySet<User>("Users");

        config.MapODataServiceRoute(
            routeName: "ODataRoute",
            routePrefix: null,
            model: builder.GetEdmModel());

        // Neither of these lines work.
        config.Formatters.JsonFormatter.SerializerSettings = new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore };
        config.Formatters.JsonFormatter.SerializerSettings.DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate;
        config.Formatters.JsonFormatter.SerializerSettings.NullValueHandling = NullValueHandling.Ignore;
    }

回答1:


Thanks Brian Rogers for pointing me in the right direction, I ended up overriding ODataEntityTypeSerializer like so:

public override ODataEntry CreateEntry(SelectExpandNode selectExpandNode, EntityInstanceContext entityInstanceContext)
{
    ODataEntry entry = base.CreateEntry(selectExpandNode, entityInstanceContext);

    // Remove any properties which are null.
    List<ODataProperty> properties = new List<ODataProperty>();
    foreach (ODataProperty property in entry.Properties)
    {
        if (property.Value != null)
        {
            properties.Add(property);
        }
    }

    entry.Properties = properties;
    return entry;
}

And then I used code from RaghuRam-Nadiminti's answer to implement a CustomSerializerProvider class which I could then use in Register.




回答2:


Although Web API iteself uses the Json.Net serializer, the MediaTypeFormatter for Web API OData uses its own internal serializer which is not Json.Net. Therefore, changing the Json.Net serializer settings in the configuration will not have any effect on OData. However, it does appear that you can implement your own ODataSerializerProvider and ODataDeserializerProvider classes to get OData to use Json.Net. See JSON.NET as a WebAPI 2 OData serializer vs ODataMediaTypeFormatter for a starting point.



来源:https://stackoverflow.com/questions/33192231/prevent-null-values-from-being-emitted-in-a-webapi-odata-v4-service

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!