Reputation: 5900
I have a model that contains an Address
property and Latitude
/Longitude
properties. The model is populated in a "Create" view, where they put in most of the other fields. I populate the Lat/Lng using the Google Maps API geocoding functionality based on the entered address (no sense in making them put this in manually).
My big question is where should this be done. The code below works, but I think it's pretty clunky. Any thoughts on a better way to integrate this behavior? Should it be in the controller? Should it be part of some internal model mechanism?
[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);
}
Upvotes: 0
Views: 219
Reputation: 1039438
You could use a repository layer to abstract the access to the Google API and then invoke this repository from the controller to give you an already populated model. This way if tomorrow you decide to use Bing instead of Google all you have to change is the implementation of the repository. No need to touch your controller or model logic.
Upvotes: 2
Reputation: 412
The main question is are you going to create churches anywhere else?
If not then this is a perfectly acceptable place to put the code.
If you are then put the code into a ChurchService which can be called from both places. That way you can Keep to DRY (Don't Repeat Yourself) principles without over complicating your code.
Upvotes: 0
Reputation: 6516
You could write a custom model binder and put all of your Google API code in there. That way your controller will be completely oblivious to your data access.
Here is a tutorial on custom model binders:
http://buildstarted.com/2010/09/12/custom-model-binders-in-mvc-3-with-imodelbinder/
Upvotes: 0