0

我有一个包含Address属性和Latitude/Longitude属性的模型。该模型填充在“创建”视图中,它们放置在大多数其他字段中。我根据输入的地址使用 Google Maps API 地理编码功能填充 Lat/Lng(让他们手动输入是没有意义的)。

我的大问题是应该在哪里完成。下面的代码有效,但我认为它很笨重。关于整合这种行为的更好方法的任何想法?它应该在控制器中吗?它应该是某些内部模型机制的一部分吗?

[HttpPost]
public ActionResult Create(Church church)
{
    try
    {
        if (ModelState.IsValid)
        {
            string address = string.Format("{0},{1},{2} {3}", 
                church.Street + church.Street2, church.City,
                church.Region, church.PostalCode);

            JObject jsonResult = GoogleApiHelper.GetAddressGeocodeData(address);

            //Handle some error states here...
            if (jsonResult["results"].Count() == 1)
            {
                church.Latitude = jsonResult.SelectToken(        
                    "results[0].geometry.location.lat").Value<double>();
                church.Longitude = jsonResult.SelectToken(
                    "results[0].geometry.location.lng").Value<double>();
                unitOfWork.ChurchRepository.Insert(church);
                unitOfWork.Save();
                return RedirectToAction("Index");
            }              
        }
    }
    catch (DataException)
    {
        //Log the error (add a variable name after DataException)
        ModelState.AddModelError("", "Unable to save changes.");
    }
    return View(church);
}
4

3 回答 3

2

您可以使用存储库层来抽象对 Google API 的访问,然后从控制器调用此存储库以提供已填充的模型。这样,如果明天您决定使用 Bing 而不是 Google,您只需更改存储库的实现即可。无需触摸您的控制器或模型逻辑。

于 2012-06-25T13:49:32.540 回答
0

您可以编写自定义模型绑定器并将所有 Google API 代码放入其中。这样,您的控制器将完全忘记您的数据访问。

这是关于自定义模型绑定器的教程:

http://buildstarted.com/2010/09/12/custom-model-binders-in-mvc-3-with-imodelbinder/

于 2012-06-25T13:55:59.303 回答
0

主要问题是你打算在其他地方建立教堂吗?

如果不是,那么这是放置代码的完全可以接受的地方。

如果您随后将代码放入可以从两个地方调用的 ChurchService 中。这样您就可以保持 DRY(不要重复自己)原则,而不会过度复杂您的代码。

于 2012-06-25T13:57:10.123 回答