I want user’s latitude and longitude to be updated on every page visited. In order not to duplicate things, I created a base controller where I also implemented the onActionExecuting which allows the method to run every time on every action from the derived controllers, but I can’t figure out how to pass the latitude and longitude parameters since they are only passed from the browser through an Ajax call.
public class BaseController : Controller
{
protected readonly UserManager<ApplicationUser> _userManager;
public BaseController(UserManager<ApplicationUser> userManager)
{
_userManager = userManager;
}
public override void OnActionExecuting(ActionExecutingContext context)
{
base.OnActionExecuting(context);
UpdateLocation(latitude, longitude); //How do I pass these parameters from Ajax?
}
public void UpdateLocation(double latitude, double longitude)
{
var user = _userManager.GetUserAsync(User);
if (user != null)
{
user.Location = new Point(latitude, longitude) { SRID = 4326 };
await _userManager.UpdateAsync(user);
}
}
}
I placed this script in the layout. It retrieves the location data and sends it to the action method.
<script>
$(document).ready(function () {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(showPosition);
}
else {
console.log($`Geolocation + {} not supported by browser.`);
}
});
function showPosition(position) {
var postData = { 'latitude': position.coords.latitude, 'longitude': position.coords.longitude };
$.ajax({
url: 'Base/UpdateLocation',
contentType: 'application/json; charset=utf-8',
type: 'GET',
data: postData,
dataType: 'json',
success: function (data) {
console.log(data);
},
error: function (request, data) {
console.log(data);
}
});
};
</script>
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
I hope I understood your question well. Here it goes:
From my experiences and brief Googling, I am under the impression that you can not retrieve coordinates from a simple HTTP request, which means, you can not receive coordinates with every page request. You could for example search for senders location by his requests IP address but that is certainly not reliable. You have to use JavaScript on the client’s side (in his browser). The way you do it is, in my opinion, a good way to do it.
From what you describe, the best approach would be to simply let your code how it is and run the script that sends coordinates on every page. This would result in the behavior that you seek. On every page load, the script runs and the user gets his coordinates updated. There will not be any duplicates if you put the script in your page layout and I think there is no need to pass the coordinates into the OnActionExecuting method.
Note: If you describe your needs further I believe we could come up with more suitable solution
Method 2
I didn’t need to implement the onActionExecuting method. I changed the UpdateLocation to an action method. Though there is no need to create a base controller, I could simply put the action method in one controller and it will be called from any controller as long as the views of that controller inherit from the layout view where the location script is placed.
public class BaseController : Controller
{
protected readonly UserManager<ApplicationUser> _userManager;
public BaseController(UserManager<ApplicationUser> userManager)
{
_userManager = userManager;
}
public async Task<JsonResult> UpdateLocation(double latitude, double longitude)
{
var user = await _userManager.GetUserAsync(User);
if (user != null)
{
user.Location = new Point(latitude, longitude) { SRID = 4326 };
await _userManager.UpdateAsync(user);
}
return Json($"Latitude: {latitude}, Longitude: {longitude}");
}
}
Then updated the location script in the layout.
<script>
$(document).ready(function () {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(showPosition);
}
else {
console.log($`Geolocation + {} not supported by browser.`);
}
});
function showPosition(position) {
var postData = { 'latitude': position.coords.latitude, 'longitude': position.coords.longitude };
$.ajax({
url: "@Url.Action("UpdateLocation", "[DerivedControllerName]")",
contentType: 'application/json; charset=utf-8',
type: 'GET',
data: postData,
dataType: 'json',
success: function (data) {
console.log(data);
},
error: function (request, data) {
console.log(data);
}
});
};
</script>
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0