0

我正在寻找是否有一种方法可以消除对我的方法对谷歌地图进行的两个调用中的一个,以计算长/纬度坐标。

这是我的方法。

    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,

所以我运行这个方法两次只是为了插入/更新一个学生。似乎有点多余。

在控制器中的代码运行时没有办法触发/设置验证状态,所以当用户提交表单时我不必调用此方法两次(一次用于验证,一次用于设置实际值) ?

我考虑过缓存,但不认为这是一个好主意,除非有人能指出一些事情。

4

1 回答 1

0

If you think applying validation upfront using an attribute on the text box serve value to the user (early feedback), keep things as it is. Two calls is not too bad at all considering the value and cleanliness of the solution.

Second option is you can remove the attribute, and perform the validation in the controller action. If validation fails, display same form with all the same data but error message for the text box value (location). User will need to choose another location and then submit.

It is a trade off.

Important Tip: You can optimize your solution by storing region names in your DB and going to google API only if the region name does not present in your DB.

于 2015-02-23T07:54:55.703 回答