2015-02-23 59 views
0

我期待看看是否有一種方法可以消除兩個調用中的一個,這些調用是通過Google地圖來計算長/緯度座標的。試圖消除驗證和實體冗餘代碼執行

這是我的方法。

public static GeocoderCoordinates GetCoordinates(string region) 
    { 
     WebRequest request = WebRequest.Create("http://maps.googleapis.com/maps/api/geocode/xml?sensor=false&address=" + HttpUtility.UrlEncode(region)); 

     using (WebResponse response = request.GetResponse()) 
     { 
      using (Stream stream = response.GetResponseStream()) 
      { 
      XDocument document = XDocument.Load(new StreamReader(stream)); 

      XElement longitudeElement = document.Descendants("lng").FirstOrDefault(); 
      XElement latitudeElement = document.Descendants("lat").FirstOrDefault(); 

      if (longitudeElement != null && latitudeElement != null) 
      { 
       return new GeocoderCoordinates 
       { 
        Longitude = Double.Parse(longitudeElement.Value, CultureInfo.InvariantCulture), 
        Latitude = Double.Parse(latitudeElement.Value, CultureInfo.InvariantCulture) 
       }; 
      } 
      } 
     } 
     return null; 
    } 

我第一次把這種方法稱爲驗證。

internal class ValidateLocationAttribute : ValidationAttribute 
{ 
    public override bool IsValid(object value) 
    { 
     var location = value as string; 

     GeocoderCoordinates coordinates = Geocoding.GetCoordinates(location); 
     if (coordinates == null) 
      return false; 

     return true; 
    } 
} 

如果沒有找到位置,則返回null - 驗證失敗。 第二次被調用是在控制器中設置我的實體內的經度/緯度座標。

[HttpPost] 
    public ActionResult Edit(EditStudentViewModel viewModel) 
    { 
     if (ModelState.IsValid) 
     { 
      Student student = studentRepository.Find(User.Identity.GetUserId()); 

      if (student == null) 
      { 
       var newStudent = new Student 
       { 
        AspNetUserRefId = viewModel.AspNetUserRefId, 
        CatchPhrase = viewModel.CatchPhrase, 
        StartedPracticing = Convert.ToInt16(viewModel.SelectedYearId), 
        LocationPoints = Geocoding.GetDbGeography(viewModel.Location), 
        Location = viewModel.Location, 

所以我正在運行這個方法兩次只是爲了插入/更新一個學生。這似乎有點多餘。

是不是有在控制器中的代碼運行時,觸發/套的驗證狀態的方式,所以我不必兩次調用此方法(一次驗證和一次設置的實際值)時,用戶提交表單?

我想過緩存但不認爲這是一個好主意,除非有人能指出一些東西。

+0

我沒有找到另一個電話給GetCoordinates。 – SBirthare 2015-02-23 06:29:34

+0

你在哪裏應用ValidateLocationAttribute? – SBirthare 2015-02-23 06:31:36

+0

我將它應用於視圖中顯示的視圖模型memeber。這是一個文本框...所以用戶進入一個位置前。舊金山,驗證方法運行。然後,如果所有驗證都通過了控制器操作方法,並且它再次調用地理位置方法來獲取位置並在提交到數據庫之前設置長/緯度值 – user1186050 2015-02-23 07:20:31

回答

0

如果您認爲使用文本框上的屬性預先應用驗證可爲用戶提供值(早期反饋),請保持原樣。考慮到解決方案的價值和清潔度,兩個調用並不算太差。

第二個選項是您可以刪除該屬性,並在控制器操作中執行驗證。如果驗證失敗,則顯示與所有相同數據相同的表單,但文本框值(位置)的錯誤消息。用戶需要選擇其他位置然後提交。

這是一個權衡。

重要提示:您可以優化您的解決方案,方法是將區域名稱存儲在您的數據庫中,並且只有在數據庫中不存在區域名稱時才轉到Google API。