如何将数据从 ajax 发送到在每个访问的页面上运行的基本控制器方法
How to send data from ajax to a base controller method that runs on every visited page
我希望在访问的每个页面上更新用户的纬度和经度。为了不重复,我创建了一个基本控制器,我还实现了 onActionExecuting,它允许该方法每次对派生控制器的每个动作执行 运行,但我不知道如何传递纬度和经度参数,因为它们仅通过 Ajax 调用从浏览器传递。
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);
}
}
}
我把这个脚本放在布局中。它检索位置数据并将其发送到操作方法。
<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>
希望我能很好地理解您的问题。开始了:
根据我的经验和简短的谷歌搜索,我的印象是您无法从简单的 HTTP 请求中检索坐标,这意味着您无法接收每个页面请求的坐标。例如,您可以通过他的请求 IP 地址搜索发件人位置,但这肯定不可靠。您必须在客户端(在他的浏览器中)使用 JavaScript。 在我看来,你这样做是一个很好的方法。
根据您的描述,最好的方法是让您的代码保持原样,运行 在每个页面上发送坐标的脚本。这将导致您寻求的行为。在每次页面加载时,脚本 运行s 和用户都会更新他的坐标。 如果将脚本放在页面布局中,将不会有任何重复,我认为没有必要将坐标传递到 OnActionExecuting
方法中。
注意:如果您进一步描述您的需求,我相信我们可以想出更合适的解决方案
我不需要实施 onActionExecuting
方法。我将 UpdateLocation 更改为操作方法。虽然不需要创建基本控制器,但我可以简单地将操作方法放在一个控制器中,只要该控制器的视图继承自放置位置脚本的布局视图,它就会从任何控制器调用。
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}");
}
}
然后更新布局中的位置脚本。
<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>
我希望在访问的每个页面上更新用户的纬度和经度。为了不重复,我创建了一个基本控制器,我还实现了 onActionExecuting,它允许该方法每次对派生控制器的每个动作执行 运行,但我不知道如何传递纬度和经度参数,因为它们仅通过 Ajax 调用从浏览器传递。
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);
}
}
}
我把这个脚本放在布局中。它检索位置数据并将其发送到操作方法。
<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>
希望我能很好地理解您的问题。开始了:
根据我的经验和简短的谷歌搜索,我的印象是您无法从简单的 HTTP 请求中检索坐标,这意味着您无法接收每个页面请求的坐标。例如,您可以通过他的请求 IP 地址搜索发件人位置,但这肯定不可靠。您必须在客户端(在他的浏览器中)使用 JavaScript。 在我看来,你这样做是一个很好的方法。
根据您的描述,最好的方法是让您的代码保持原样,运行 在每个页面上发送坐标的脚本。这将导致您寻求的行为。在每次页面加载时,脚本 运行s 和用户都会更新他的坐标。 如果将脚本放在页面布局中,将不会有任何重复,我认为没有必要将坐标传递到 OnActionExecuting
方法中。
注意:如果您进一步描述您的需求,我相信我们可以想出更合适的解决方案
我不需要实施 onActionExecuting
方法。我将 UpdateLocation 更改为操作方法。虽然不需要创建基本控制器,但我可以简单地将操作方法放在一个控制器中,只要该控制器的视图继承自放置位置脚本的布局视图,它就会从任何控制器调用。
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}");
}
}
然后更新布局中的位置脚本。
<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>