создание относительных URL-адресов для приложения MVC с помощью JavaScript - PullRequest
10 голосов
/ 17 марта 2012

У меня проблемы с получением C # и JavaScript / jQuery для хорошей игры.

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

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

Обычно в MVC3 я бы использовал что-то вроде @Url.Action и позволил бы стороне сервера создать адрес ... но опять же, хитрость в том, что C # не знает об изменении значений 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) ивсе еще карта из относительного корня приложения?

Ответы [ 3 ]

18 голосов
/ 17 марта 2012

То, как мы делаем это в моем проекте MVC 3, заключается в том, чтобы включить в мастер-макет следующее:

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

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

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

url: baseSiteURL + 'vendors/' + viewModel.count() + '/' + viewModel.filterText()
16 голосов
/ 17 марта 2012

Одна возможность - отправить эти значения 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);
    }
});
3 голосов
/ 17 марта 2012

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

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

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

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

...