2013-01-09 31 views
0

我正在與MVC asp.net 4和jquery。 這裏是我的問題: 我有以下型號:未能通過抽象列表屬性發送模型通過jquery ajax

public class PledgeModel 
{ 
    public string name { get; set; } 
    public IList<AbstractAsset> Assets { get; set; } 
} 

之一,如果它的屬性是對象的名單,他們每個人的繼承抽象類:

public abstract class AbstractAsset 
{ 
    public string commetns { get; set; } 
} 


public class RealEstateAsset:AbstractAsset 
{ 
    public int CityId { get; set; } 
} 
public class TransportationAsset : AbstractAsset 
{ 
    public string LicenseNumber { get; set; } 
} 

}

這裏是我的「獲取」動作代碼:

 //init new Pledge 
     PledgeModel pledge=new PledgeModel(); 
     pledge.name = "Moses"; 
     pledge.Assets=new List<AbstractAsset>(); 

     RealEstateAsset realEstateAsset = new RealEstateAsset(); 
     TransportationAsset transportationAsset=new TransportationAsset(); 

     realEstateAsset.CityId = 1; 
     transportationAsset.LicenseNumber = "7654321"; 

     pledge.Assets.Add(realEstateAsset); 
     pledge.Assets.Add(transportationAsset); 


     ViewBag.Pledge = pledge; 

當我得到承諾模型在JSON的觀點我越來越關注JSON:

{「name」:「摩西」,「資產」:[{「CityId」:1,「commetns」:null}, {「LicenseNumber」 「7654321」, 「commetns」:空}]};

如果我試圖發送整個模型和Ajax回調的資產清單:

       var ajaxOptions = { 
           type: 'post', 
           url: 'Home/TryInsertPledge', 
           contentType: "application/json, charset=utf-8;", 
           dataType:'json', 
           data:JSON.stringify({pledge:pledge}), 
           success: function(data) { 
            alert('success'); 
           }, 
           error: function() { 
            alert('error'); 
           } 
           }; 
           $.ajax(ajaxOptions); 

「後」動作:

[HttpPost] 
    public JsonResult TryInsertPledge(PledgeModel pledge) 
    { 


     return Json(new {sucess = "success"}); 
    } 

出於某種原因,我得到錯誤(如果您點擊鉻開發工具中的請求紅色錯誤)'無法創建抽象類'

但是,如果資產列表爲空 - 我得到了我的承諾

請幫

感謝

+0

是您的jQuery ajax擊中控制器操作? –

+0

如果我評論所有設置資產列表的全部內容-yes – happyZZR1400

+0

爲您的表單提供一個id,然後在數據屬性數據中嘗試以下操作:$('#formname')。serialize(); –

回答

0

在你的Ajax調用被產生什麼承諾?如果它需要確保每個抽象資產的所有屬性都以某種方式包含在表單中。如果您不希望這些是用戶可編輯的輸入字段,請將輸入字段上的類型設置爲隱藏。

希望有幫助!

+0

嗨,與此同時我沒有輸入測試(JSON我來自viewbag:var pledge = @(Html.Raw(Json.Encode(ViewBag。承諾)));) – happyZZR1400

+0

嘗試數據:承諾,在您的Ajax調用中假設承諾已經是ajax –

0

感謝http://maciejlis.com/asp-mvc-3-model-binder-with-abstract-class-support/ 我得到了解決我的問題:

我已經加入customBinder(從maciejlis博客完全複製) 該定製綁定根據type屬性(必須是完全一樣映射資產對象資產班組長名)

public class EnhancedDefaultModelBinder : DefaultModelBinder 
    { 
     protected override object CreateModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Type modelType) 
     { 
      Type type = modelType; 
      if (modelType.IsGenericType) 
      { 
       Type genericTypeDefinition = modelType.GetGenericTypeDefinition(); 
       if (genericTypeDefinition == typeof(IDictionary<,>)) 
       { 
        type = typeof(Dictionary<,>).MakeGenericType(modelType.GetGenericArguments()); 
       } 
       else if (((genericTypeDefinition == typeof(IEnumerable<>)) || (genericTypeDefinition == typeof(ICollection<>))) || (genericTypeDefinition == typeof(IList<>))) 
       { 
        type = typeof(List<>).MakeGenericType(modelType.GetGenericArguments()); 
       } 
       return Activator.CreateInstance(type); 
      } 
      else if (modelType.IsAbstract) 
      { 
       string concreteTypeName = bindingContext.ModelName + ".Type"; 
       var concreteTypeResult = bindingContext.ValueProvider.GetValue(concreteTypeName); 

       if (concreteTypeResult == null) 
        throw new Exception("Concrete type for abstract class not specified"); 

       type = Assembly.GetExecutingAssembly().GetTypes().SingleOrDefault(t => t.IsSubclassOf(modelType) && t.Name == concreteTypeResult.AttemptedValue); 

       if (type == null) 
        throw new Exception(String.Format("Concrete model type {0} not found", concreteTypeResult.AttemptedValue)); 

       var instance = Activator.CreateInstance(type); 
       bindingContext.ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(() => instance, type); 
       return instance; 
      } 
      else 
      { 
       return Activator.CreateInstance(modelType); 
      } 
     } 
    } 

現在所有剩下的就是「類型」屬性添加到每個資產對象:

  $(pledge.Assets).each(function() { 

       this.Type = (typeof this.CityId !== 'undefined') ? 'RealEstateAsset' : 'TransportationAsset'; 

      }); 





      var ajaxOptions = { 
       type: 'post', 
       url: 'Home/TryInsertPledge', 
       dataType: 'json', 
       contentType: "application/json, charset=utf-8;", 
       data: JSON.stringify({ pledge: pledge }), 
       success: function (data) { 

         alert('success'); 
       }, 
       error: function (xhr) { 
        alert(xhr.respnseText); 
       } 
      }; 
      $.ajax(ajaxOptions); 

並且資產到服務器正確... 再次感謝您maciejlis

+0

對您的方法進行一些重構,請實現抽象工廠模式,將雅? – IamStalker