Подтвердить что ты не робот

Создание относительных URL-адресов для приложения MVC с использованием JavaScript

У меня возникли проблемы с получением С# и JavaScript/jQuery, чтобы играть здесь хорошо.

У меня есть модель представления нокаута, простой старый объект javascript... один из его свойств/методов запускает вызов .ajax(), а параметр url построен с использованием некоторых других его значений свойств (переменные javascript).

Это отлично работает, когда полностью содержится в JavaScript, но при развертывании в качестве приложения для IIS относительная траектория запускается.

В MVC3 я обычно использовал бы что-то вроде @Url.Action и позволял стороне сервера строить адрес... но опять же, трюк С# не знает об изменениях значений JavaScript.

Код:

var viewModel = {
    vendors: ko.observableArray([]),
    count: ko.observable(10),
    page: ko.observable(1),
    filterText: ko.observable(""),
    submit: function () {
        $.ajax({
            // works fine, until deploy when it is no longer a site relative URL
            url: 'vendors/' + viewModel.count() + '/' + viewModel.filterText(),

            // does not work, because C# is unaware of the javascript variables.
            //url: @Url.Action("Vendors", "Home", new { count = viewModel.count(), filter = viewModel.filterText() })

            dataType: 'json',
            success: function (data) {
                viewModel.vendors(data);
            }
        });    
    }
    // next: // load sequence starting with (page+1 * count) 
    // previous: // load sequence starting with (page-1 * count)
};
ko.applyBindings(viewModel);

Вопрос:

Тогда мой вопрос: как я могу построить url для вызова ajax с использованием значений переменной javascript (например, count, filterText) и по-прежнему отображать от относительного корня приложения?

4b9b3361

Ответ 1

Одна возможность отправить эти значения javascript в качестве параметров запроса:

$.ajax({
    url: '@Url.Action("vendors")',
    data: { count: viewModel.count(), filter: viewModel.filterText() },
    dataType: 'json',
    success: function (data) {
        viewModel.vendors(data);
    }
});

Конечно, это означает, что вы используете маршруты по умолчанию, и параметры просто будут отправляться на сервер либо в виде параметров строки запроса (если вы используете GET), либо как часть тела запроса POST. В обоих случаях вы получите их на сервере одинаково:

public ActionResult Vendors(int count, string filter)
{
    ...
}

Другая возможность, если вы абсолютно настаиваете на том, чтобы иметь некоторые пользовательские маршруты для ваших запросов AJAX, будет использовать замену простой строки:

var url = '@Url.Action("vendors", new { count = "__count__", filter = "__filterText__" })';
url = url.replace('__count__', viewModel.count())
         .replace('__filter__', viewModel.filterText());
$.ajax({
    url: url,
    dataType: 'json',
    success: function (data) {
        viewModel.vendors(data);
    }
});

Ответ 2

То, как мы это делаем в моем проекте MVC 3, должно включать следующее в макет основного файла:

<script type="text/javascript">
    var baseSiteURL = '@Url.Content("~/")';
</script>

Затем вы просто добавляете это к своим URL-адресам в JavaScript.

Что в вашем примере будет читать:

url: baseSiteURL + 'vendors/' + viewModel.count() + '/' + viewModel.filterText()

Ответ 3

Даринский ответ является наиболее надежным, но он требует отправки данных с использованием параметров строки запроса на вызов ajax.

Чтобы этого избежать, я просто обернул метод @Url.Action() в кавычки и добавил значения javascript, как я предполагал.

url: "@Url.Action("Vendors", "Home")/" + viewModel.count() + "/" + viewModel.filterText(),

В конечном итоге это дало наилучшие результаты, так как это позволило мне сохранить очень чистый URL... Request.ApplicationPath казался слишком хакерским и может технически быть нулевым... @Url.Content() предназначен для статических "контентов" путей (например, изображений, скрипты)... и т.д.