2013-04-23 19 views
5

yerine başarısız serileştirme üzerinde boş bir nesne oluşturur WebAPI'de, doğrulama uygulamalarımızla uğraşan bir tutarsızlık fark ettim. Xml'de bir POST ile kötü bir gövde/yük yükü gönderirseniz, deserialization başarısız olur ve boş bir işaretçi alırsınız. JSON'ta kötü bir gövde/yük gönderirseniz, bunun yerine boş bir nesne alırsınız. Yanıltıcıdır ve bundan hoşlanmıyorum. Bir boş gösterici başarısız bir json serpiştirmesi ile zorlamak için bir yolu var mı?JSON serializer, null

GÜNCELLEME: Bir seri hale getirme sorunu yaşıyorum. DataContractSerializer ve Json.net serializer arasında bir fark gibi görünen bir davranış sorunu yaşıyorum. Xml serileştirilemediğinde, yük boştur. Ancak, Json'un seri üretime geçememesi durumunda, beklenen yükün varsayılan bir örneğini başlatıyor gibi görünüyor. Kötü bir xml yükünün

Örnek: Kötü bir json yükünü kullanarak aynı çağrının enter image description here

Örnek

enter image description here

(. yük bunun yerine yük sınıfının bir varsayılan örnek null değildir)
+1

Eğer bu farkı gösteriyor kodunu paylaşabilir ki? –

+0

Sizi giriş noktasında nasıl göreceğinizden emin değilim. – Sinaesthetic

+1

Evet, yeni başlayanlar için, modelinizi gösterin, bu modeli argüman olarak alan Web API denetleyicinizin eylemini gösterin ve davranışta gözlemlediğiniz tam farklılıkları açıklayan bu eylemi gönderdiğiniz XML ve JSON'u gösterin.Bu, bu sorunun şu anki aşamasında oldukça zor olan yapıcı bir tartışmayı başlatmak için yeterli olmalıdır. –

cevap

4

Web.API, varsayılan olarak JsonMediaTypeFormatter'da MissingMemberHandling.Ignore ayarını kullandı.

Sen ile MissingMemberHandling.Error olarak ayarlayın gerekir:

GlobalConfiguration.Configuration 
    .Formatters.JsonFormatter 
    .SerializerSettings.MissingMemberHandling = MissingMemberHandling.Error; 

ve benzeri JSON gönderirken null almalısınız: Eğer {} sonra: Ancak

{ 
    "somenotexistingprop": "" 
} 

Bir tamamen boş JSON nesnesi gönderirseniz null değil, boş özelliklere sahip bir nesne almaya devam edecektir. JsonConvert.DeserializeObject boş bir nesne döndürdüğü için boş bir nesne döndürür (github bu birim sınama bakın). Benim ekip üyelerinden birinin ardından

+0

Bunu şimdi de buldum. Işe yaramadı. Aynı sonuç! – Sinaesthetic

+0

@Sinaesthetic Benim cevabımı geri aldım çünkü bu sizin sorununuz için bir çözümdür, ancak şu anda Wep.API'de bunun çalışmasını engelleyen bir hata var gibi görünmektedir ... – nemesv

+1

MissingMemberHandling'i "Error" (Hata) 'ya getirmekten başka Xml ve Json biçimlendiricileri arasında tutarlı olması için aşağıdaki denetimi yapın (if (! ModelState.IsValid) { yeni HttpResponseException (Request.CreateErrorResponse (HttpStatusCode.BadRequest, this.ModelState)); } ' –

1

beni bu senaryo hakkında bazı notlar neden bu durumda, anlaşılması aşağıdaki yardımcı:

varsayılan olarak
  1. Biz "MissingMemberHandling.Error" yok Json Formatlayıcıdaki bu çünkü İstemcinin daha yeni bir sürümü ile daha eski bir hizmet sürümüne veri gönderen senaryolarda yardımcı olabilir. Hizmetin eski sürümü hala bu isteği kabul etmeli ve ekstra özellikleri görmezden gelebilmelidir. Bu davranış, Xml biçimlendiricinin nasıl davrandığıyla tutarlıdır.

  2. @Sinaesthetic: "MissingMemberHandling.Error" ayarını yapıyorsanız ve yalnızca "ModelState.IsValid" denetimine güvenmek istemiyorsanız, isteğinizin gerçekten geçersiz olup olmadığını anlamak için ModelState Keys özelliğini kontrol edebilirsiniz. eksik bir üye ya da başka bir şey yüzünden.

Örnek aşağıda:

public class Customer 
{ 
    public int Id { get; set; } 

    [MaxLength(5)] 
    public string Name { get; set; } 

    public Address Address { get; set; } 
} 

public class Address 
{ 
    public string Line1 { get;set;} 
} 

//action 
public void Post([FromBody]Customer customer) 
    { 
     if (!ModelState.IsValid) 
     { 
      ModelStateDictionary msd = new ModelStateDictionary(); 

      foreach (string key in ModelState.Keys) 
      { 
       if (ModelState[key].Errors.Count > 0) 
       { 
        foreach (ModelError error in ModelState[key].Errors) 
        { 
         Exception ex = error.Exception; 

         if (ex != null 
          && typeof(JsonSerializationException).IsAssignableFrom(ex.GetType()) 
          && ex.Message.StartsWith("Could not find member")) 
         { 
          msd.AddModelError(key, ex); 
         } 
        } 
       } 
      } 

      if (msd.Count > 0) 
      { 
       throw new HttpResponseException(Request.CreateErrorResponse(HttpStatusCode.BadRequest, msd)); 
      } 
     } 

     //process the supplied customer 
    } 
İlgili konular