2015-02-23 28 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。