2011-07-10 78 views
0

在此之前,另外一個問題我在這裏問:Find nearby entities with Bing Maps REST controlASP.NET MVC 3 ContentResult類型將不會接受類繼承另一個類

在上面的問題,內部的功能DisplayResults(響應),我的環已經添加以下代碼:

var loc = new Array(); 
    loc[0] = results[i].Longitude; 
    loc[1] = results[i].Latitude; 

    var address = { 
     AddressLine1: results[i].Address, 
     City: results[i].City, 
     State: results[i].StateOrProvince, 
     PostalCode: results[i].PostalCode, 
     Latitude: results[i].Latitude, 
     Longitude: results[i].Longitude, 
     Country: results[i].CountryOrRegion, 
     ID: results[i].UniqueId 
    }; 

    $.ajax({ 
     url: "/Home/AddAddressToCollection", 
     type: 'post', 
     data: JSON.stringify(address), 
     contentType: 'application/json', 
     dataType: 'json' 
    }); 

這上面的代碼構造從包含在所得到的數據集合中的每個地址的地址,並將其發送回作爲其目的是爲每個地址存儲到背面,它返回一個空一個ContentResult類型最後是MongoDB。您可能想知道爲什麼我採用這種方法 - 地址是MongoDB的種子數據。這個想法是,這是一個開源項目,我想添加一些個性化來與開發人員的GeoLocation一起工作,爲他們提供與他們檢測到的位置相對應的本地化地址集(該代碼全部在我以前的文章中)。

這裏是ContentResult類型在HomeController的代碼:

[HttpPost] 
    public ContentResult AddAddressToCollection(Address address) 
    { 
     address.GeoInsert(_dbName, ref _repository); 
     return null; 
    } 

此代碼與corresponing POST方法工作時,我的地址類看起來像這樣:

公共類地址 { 私人雙_latitude ; private double _longitude;

[Key] 
    [Required] 
    [HiddenInput(DisplayValue=false)] 
    public string ID { get; set; } 

    [Required] 
    [HiddenInput(DisplayValue = false)] 
    public virtual Guid AccountID { get; set; } 

    [Required] 
    [Display(Name = "Address Line 1")] 
    public string AddressLine1 { get; set; } 

    [Display(Name = "Address Line 2")] 
    public string AddressLine2 { get; set; } 

    [Required] 
    [Display(Name = "City")] 
    public string City { get; set; } 

    [Required] 
    [Display(Name = "State")] 
    public string State { get; set; } 

    [Required] 
    [Display(Name = "Zip Code")] 
    public string PostalCode { get; set; } 

    public string Country { get; set; } 

    [Required] 
    [HiddenInput(DisplayValue = false)] 
    public double[] Location { get; set; } 

    [Required] 
    [HiddenInput(DisplayValue = false)] 
    public double Latitude 
    { 
     get { return _latitude; } 
     set 
     { 
      Location[1] = value; 
      _latitude = value; 
     } 
    } 

    [Required] 
    [HiddenInput(DisplayValue = false)] 
    public double Longitude 
    { 
     get { return _longitude; } 
     set 
     { 
      Location[0] = value; 
      _longitude = value; 
     } 
    } 

    public Address() 
    { 
     Location = new double[2]; 
    } 

    public void GeoInsert(string dbName, ref Repository repository) 
    { 
     repository.MongoGeoInsert(dbName, this); 
    } 

    public Dictionary<Address, double> GeoNear(string dbName, ref Repository repository, double maxKilometers, int limitResults) 
    { 
     return repository.MongoGeoNear<Address>(dbName, this.Latitude, this.Longitude, maxKilometers, limitResults); 
    } 

} 

但在這裏就是我很好奇......雖然我不需要這些,現在,我最初試圖讓所有我的班在我的模型,從同一個基類繼承,以幫助一些自定義我使用的序列化方法。當我從這樣一個類繼承...讓我們稱之爲BaseClass,POST不再起作用,並且我從服務器得到500響應......我只是不清楚原因是什麼。下面是我正在談論的一個例子(ps,如果你碰巧使用了下面的任何代碼,只是提示你應該弄清楚如何使用字典進行序列化......它速度更快,但人們更熟悉與反射所以這就是我在這裏)要:

如此之快,爲Address類我會:

地址:BaseClass的

和構造將是...

地址:base(「Address」) { //儘管base(「Address」)不是必需的除非您使用的字典 //序列化方法 }

現在

的BaseClass的...

public class Serialization 
{ 
    public abstract class BaseObject 
    { 
     [BsonId(IdGenerator = typeof(CombGuidGenerator))] 
     public Guid? Id { get; set; } 

     public string ObType { get; private set; } 

     public BaseObject() : this("base") { } 

     public BaseObject(string obType) 
     { 
      ObType = obType; 
      Id = Guid.NewGuid(); 
     } 

     public virtual BaseObject Parse(XElement xml) 
     { 
      PropertyInfo[] properties = this.GetType().GetProperties(); 

      foreach (var property in properties) 
      { 
       ElementName attribute = Attribute.GetCustomAttribute(property, typeof(ElementName)) as ElementName; 
       if (attribute == null) continue; 

       object value = null; 
       string stringValue = xml.Element(attribute.Name).Value; 

       switch (property.PropertyType.Name.ToLower()) 
       { 
        case "double": 
         { 
          value = double.Parse(stringValue); 
          break; 
         } 
        default: 
         { 
          value = stringValue; 
          break; 
         } 
       } 

       property.SetValue(this, value, null); 
      } 

      return this; 
     } 

    } 

    public class Serializer 
    { 
     public static T Deserialize<T>(XElement xml) 
      where T : BaseObject, new() 
     { 
      BaseObject obj = new T() as BaseObject; 
      if (obj != null) 
      { 
       //populate obj properties... 
       obj.Parse(xml); 
      } 
      return obj as T; 
     } 
    } 
} 

好吧,我想這應該是足夠的信息...任何想法是什麼不會工作?希望我不會錯過這裏非常明顯的東西......但我比Silverlight編程做了更多的Silverlight,所以完全有可能我是0 :)

謝謝!

+0

你可以打開螢火蟲,並告訴我們你收到什麼錯誤? –

+0

是的,這是一個非常標準的500錯誤: POST/Home/AddAddressToCollection 500內部服務器錯誤 我想這與MVC框架如何處理內容和操作結果有關,因爲我知道客戶端上的代碼正在工作(因爲它在我不從BaseClass繼承時起作用) – Jordan

回答

0

所以這裏第一個問題是你的問題的範圍是方式太大。

您首先向此「黑匣子」服務器發送AJAX請求。但是事實證明,你有服務器的代碼,所以爲什麼我首先關心AJAX請求呢?開始的地方:

  1. 你確定序列化工作正常嗎?你有一個測試證明你的自定義序列化基類實際上有效嗎? (它應該是微不足道的假輸入)如果沒有,你可能會得到一個錯誤。
  2. 數據是否正確進入MongoDB?如果沒有,你可能會拋出一個異常並得到你的錯誤。請注意,CSharp驅動程序has its own serialization。你可能會破壞它。
  3. 你能否確認相同的數據正在進入視圖?你的觀點可能會炸燬B/C你取決於一些不正確的領域。

總之,這個問題應該很容易用典型的單元測試覆蓋率進行診斷。你對一個類做了一個改變,所以你的測試套件應該拋出一些非常明確的信息,可能是上述三個信息之一。

如果你的測試套件沒有發現任何錯誤,那麼你顯然錯過了一些重要的測試。

如果您沒有任何測試覆蓋,現在可能是開始的好時機。

+0

序列化代碼已經過全面測試,但本例中我沒有使用序列化。爲了澄清,我加入這個班級的遠見,我可能想在路上使用序列化,但這不是問題。我知道代碼工作,所以我敢肯定它與MVC框架引發內部錯誤有關。沿着這些線路 - 當然,我沒有解釋這個錯誤,但是如果我對這個錯誤進行了測試,爲什麼我會問這個問題呢? – Jordan

+0

蓋茨,萬一你被我的Mongo代碼拋出,我寫了一組自定義的Mongo操作來簡化Mongo的使用。我對Mongo系列化非常熟悉,這與此無關。爲了簡化互操作性並減少傳輸/存儲成本,我經常在傳遞或存儲關於特定類的數據時使用自定義xml/json序列化器。 – Jordan