Remove null properties of an object sent to Json MVC

前端 未结 3 708
花落未央
花落未央 2020-12-17 18:51
namespace Booking.Areas.Golfy.Models
{
    public class Time
    {
        public string   time            { get; set; }
            


        
相关标签:
3条回答
  • 2020-12-17 19:32

    You can't use the default Json ActionResult to remove null properties.

    You can take a look at JSON.NET, it has an attribute that you can set to remove the property if it is null

    [JsonProperty(NullValueHandling=NullValueHandling.Ignore)]
    

    Or if you don't want to use other libraries you can create your own json custom ActionResult and register a new converter for the default JavaScriptSerializer, like this:

    public class JsonWithoutNullPropertiesResult : ActionResult
    {
        private object Data { get; set; }
    
        public JsonWithoutNullPropertiesResult(object data)
        {
            Data = data;
        }
    
        public override void ExecuteResult(ControllerContext context)
        {
            HttpResponseBase response = context.HttpContext.Response;
            response.ContentType = "application/x-javascript";
            response.ContentEncoding = Encoding.UTF8;
    
            if (Data != null)
            {
                JavaScriptSerializer serializer = new JavaScriptSerializer();
                serializer.RegisterConverters(new[] { new NullPropertiesConverter() });
                string ser = serializer.Serialize(Data);
                response.Write(ser);
            }
        }
    }
    
    public class NullPropertiesConverter : JavaScriptConverter
    {
        public override IDictionary<string, object> Serialize(object obj, JavaScriptSerializer serializer)
        {
            var toSerialize = new Dictionary<string, object>();
    
            foreach (var prop in obj.GetType()
                                    .GetProperties(BindingFlags.Instance | BindingFlags.Public)
                                    .Select(p => new
                                    {
                                        Name = p.Name,
                                        Value = p.GetValue(obj)
                                    })
                                    .Where(p => p.Value != null))
            {
                toSerialize.Add(prop.Name, prop.Value);
            }
    
            return toSerialize;
        }
    
        public override object Deserialize(IDictionary<string, object> dictionary, Type type, JavaScriptSerializer serializer)
        {
            throw new NotImplementedException();
        }
    
        public override IEnumerable<Type> SupportedTypes
        {
            get { return GetType().Assembly.GetTypes(); }
        }
    }
    

    And now in your view:

    public ActionResult Index()
    {
        Teetimes r = BookingManager.GetBookings();
        return new JsonWithoutNullPropertiesResult(t);
    }
    
    0 讨论(0)
  • 2020-12-17 19:32

    I always had problems with framework-embedded json serializer, therefore I use Json.NET. Here's little example testing these two serializers:

    public class Model {
        public int Id { get; set; }
        public string Name { get; set; }
    
        public bool ShouldSerializeName() {
            return Name != null;
        }
    }
    
    class Program {
        static void Main(string[] args) {
            var t1 = new Model {
                Name = "apw8u3rdmapw3urdm",
                Id = 298384
            };
            var t2 = new Model {
                Id = 234235
            };
    
            Test(t1);
            Test(t2);
        }
    
        static void Test(Model model) {
            Console.WriteLine("JSon from .Net: {0}", ToJson(model));
            Console.WriteLine("JSon from JSon.Net: {0}", ToDotNetJson(model));
        }
    
        static string ToJson(Model model) {
            var s = new JavaScriptSerializer();
            return s.Serialize(model);
        }
    
        static string ToDotNetJson(Model model) {
            return JsonConvert.SerializeObject(model);
        }
    }
    

    You have to include System.Web.Extensions as dependency and install Json.Net with nuget to have the example working.

    Here's some documentation form Json.NET and Framework-embedded serializer

    0 讨论(0)
  • 2020-12-17 19:43

    The answers given are interresting, but I had started using DataContractJsonSerializer in the meantime.
    And it does the job fine without the need of using a third party framework (though JSON.Net does seem like widely used).

    public ActionResult Index(
        string date
        , int? courseid = null
        , int? clubid = null
        , int? holes = null
        , int? available = null
        , int? prices = null
    )
    {
        var DateFrom = DateTime.ParseExact(date, "yyyy-MM-dd", CultureInfo.InvariantCulture);
    
        MTeetimes r = BookingManager.GetBookings(new Code.Classes.Params.ParamGetBooking()
        {
            ClubID = clubid
            , DateFrom = DateFrom
            , DateTo = DateFrom.AddDays(1)
            , GroundID = courseid
        });
    
        // return Json(r, JsonRequestBehavior.AllowGet);
    
        string response;
        var serializer = new DataContractJsonSerializer(typeof(MTeetimes));
    
        // Serialize
        using (var ms = new MemoryStream())
        {
            serializer.WriteObject(ms, r);
            response = Encoding.Default.GetString(ms.ToArray());
        }
    
        return Content(response);
    }
    


    [DataContract]
    public class Time
    {
        [DataMember(Name="time", EmitDefaultValue = false)]
        public string Time
        {
            get;
            set;
        }
    
        [DataMember(Name = "holes", EmitDefaultValue = false)]
        public int Holes
        {
            get;
            set;
        }
    
        [DataMember(Name = "slots_available", EmitDefaultValue = false)]
        public int Slots_available
        {
            get;
            set;
        }
    
        [DataMember(Name = "price", EmitDefaultValue = false)]
        public decimal? Price
        {
            get;
            set;
        }
    
        [DataMember(Name = "nextcourseid", EmitDefaultValue = false)]
        public int? Nextcourseid
        {
            get;
            set;
        }
    
        [DataMember(Name = "allow_extra", EmitDefaultValue = false)]
        public bool? Allow_extra
        {
            get;
            set;
        }
    }
    
    0 讨论(0)
提交回复
热议问题