0

経度/緯度座標を計算するために Google マップへのメソッドに対して行われる 2 つの呼び出しのうちの 1 つを排除する方法があるかどうかを調べています。

これが私の方法です。

    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 を返します - 検証は失敗します。2 回目に呼び出されるのは、エンティティ内で経度/緯度の座標を設定するためのコントローラーです。

[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,

SO 学生を挿入/更新するためだけに、このメソッドを 2 回実行しています。少し冗長に思えます。

コントローラーのコードの実行中に検証状態をトリガー/設定する方法はないので、ユーザーがフォームを送信するときに、このメソッドを 2 回 (検証用に 1 回、実際の値を設定するために 1 回) 呼び出す必要はありません。 ?

キャッシングについて考えましたが、誰かが何かを指摘できない限り、それは良い考えではないと思います。

4

1 に答える 1

0

テキスト ボックスの属性を使用して事前に検証を適用することがユーザーに価値をもたらすと考えている場合 (初期のフィードバック)、そのままにしておいてください。ソリューションの価値と清潔さを考えると、2 回の呼び出しはそれほど悪くはありません。

2 番目のオプションは、属性を削除し、コントローラー アクションで検証を実行することです。検証が失敗した場合、すべて同じデータを含む同じフォームを表示しますが、テキスト ボックスの値 (場所) のエラー メッセージを表示します。ユーザーは別の場所を選択して送信する必要があります。

それはトレードオフです。

重要なヒント: リージョン名を DB に保存し、リージョン名が DB に存在しない場合にのみ Google API にアクセスすることで、ソリューションを最適化できます。

于 2015-02-23T07:54:55.703 に答える