2014-01-07 88 views
10
namespace Booking.Areas.Golfy.Models 
{ 
    public class Time 
    { 
     public string time   { get; set; } 
     public int  holes   { get; set; } 
     public int  slots_available { get; set; } 
     public decimal? price   { get; set; } 
     public int?  Nextcourseid { get; set; } 

     public bool ShouldSerializeNextcourseid 
     { 
      get 
      { 
       return this.Nextcourseid != null; 
      } 
     } 

     public bool? allow_extra { get; set; } 

     public bool ShouldSerializeallow_extra 
     { 
      get 
      { 
       return this.allow_extra != null; 
      } 
     } 
    } 
} 


刪除發送到JSON MVC一個對象的空值屬性

namespace Booking.Areas.Golfy.Controllers 
{ 
    public class TeetimesController : Controller 
    { 
     // 
     // GET: /Golfy/Teetimes/ 
     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); 

      Teetimes r = BookingManager.GetBookings(new Code.Classes.Params.ParamGetBooking() 
      { 
       ClubID = clubid 
       , DateFrom = DateFrom 
       , DateTo = DateFrom.AddDays(1) 
       , GroundID = courseid 
      }); 

      return Json(r, JsonRequestBehavior.AllowGet); 
     } 
    } 
} 

上面的web服務返回JSON字符串與時間的幾個intance。

我希望屬性Nextcourseid和allow_extra在值爲空時不會被輸出。

我試了ShouldSerializeXxx,但它似乎並沒有工作。
供參考:我也嘗試過[ScriptIgnore],但不是有條件的。

回答

2

我總是有框架嵌入式json串行器的問題,因此我使用Json.NET。下面是小例子測試這兩個串行:

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); 
    } 
} 

你必須包括System.Web.Extensions的依賴,並與安裝的NuGet到Json.Net有例子的工作。

下面是一些文檔形式Json.NETFramework-embedded serializer

11

不能使用默認Json ActionResult刪除空的屬性。

你可以看看JSON.NET,它可以設置,如果它是空

[JsonProperty(NullValueHandling=NullValueHandling.Ignore)] 

或者,如果你不想用到其他庫,您可以創建到刪除的財產屬性您自己的JSON定製的ActionResult並註冊新的轉換器爲默認JavaScriptSerializer,像這樣:

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(); } 
    } 
} 

現在在你看來:

public ActionResult Index() 
{ 
    Teetimes r = BookingManager.GetBookings(); 
    return new JsonWithoutNullPropertiesResult(t); 
} 
+1

'JsonProperty'設置完美。謝謝。 – Kon

2

給出的答案是interresting,但我同時開始使用DataContractJsonSerializer
它不需要使用第三方框架就可以很好地完成工作(儘管JSON.Net似乎被廣泛使用)。

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; 
    } 
}