如何将数据从 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>