Как данные должны передаваться между клиентским Javascript и C # кодом в приложении ASP.NET?

21

Я ищу наиболее эффективный / стандартный способ передачи данных между клиентским кодом JavaScript и кодом C # в приложении ASP.NET. Я использовал следующие методы для достижения этой цели, но все они чувствуют себя немного выдумкой.

Чтобы передать данные из JavaScript в код C #, нужно установить скрытые переменные ASP и запустить обратную передачу:

<asp:HiddenField ID="RandomList" runat="server" />

function SetDataField(data) {
      document.getElementById('<%=RandomList.ClientID%>').value = data;
}

Затем в коде C # я собираю список:

protected void GetData(object sender, EventArgs e)
{
      var _list = RandomList.value;
}

Возвращаясь к другому пути, я часто использую ScriptManager для регистрации функции и передачи ей данных во время Page_Load:

ScriptManager.RegisterStartupScript(this.GetType(), "Set","get("Test();",true);

или я добавляю атрибуты к элементам управления перед публикацией или на этапах инициализации или предварительного рендеринга:

Btn.Attributes.Add("onclick", "DisplayMessage("Hello");");

Эти методы хорошо послужили мне и делают свою работу, но они просто не чувствуют себя законченными. Существует ли более стандартный способ передачи данных между клиентским JavaScript и внутренним кодом C #?

Я видел некоторые сообщения , как этот , которые описывают HTMLElement класса; это то, что я должен посмотреть?

cwc1983
источник
5
json.org
Одед
Это зависит от того, что вы подразумеваете под передачей данных между сервером и клиентом. Если данные известны в момент отрисовки страницы, то вполне разумно добавить скрипт для создания ваших данных или установить JSON с помощью литерала или аналогичного или другого варианта. Если, OTOH, вы пытаетесь создать страницу, которая взаимодействует с сервером без обратной передачи, тогда это совершенно другая проблема. Определенно посмотрите на JSON.
Мерф
Например. Если я запустил кнопку от клиента, который получил некоторые данные из файла XML. Затем производятся некоторые расчеты по данным в C #. Затем я хочу, чтобы этот законченный результат отображался в симпатичном графическом отображении JavaScript. Это один постбэк, в котором клиент не знает результат до тех пор, пока постбэк не был поднят.
cwc1983
Из этого комментария вы все еще можете выполнять всю работу на сервере - загрузить / обработать / вернуть - так что, во-первых, я бы сделал именно это. Отформатируйте данные как json, включите json при рендеринге страницы (литерал позволит вам сделать это). Когда вы заставите это работать, вы, вероятно, захотите сделать что-то более асинхронное - но это будет тот же самый json.
Мерф
Спасибо всем. Прочитав совет здесь и проведя дополнительное исследование, я нашел новый метод достижения того, что я хотел сделать. Основная проблема, которую я получал, заключалась в том, что когда я выполнял пост Ajax, я не мог получить код на стороне клиента, чтобы запомнить, где была программа. Сейчас я использую JQuery $ Ajax.Post, поскольку он возвращает сообщение об успешном завершении клиенту, сохраняя данные сеанса.
cwc1983

Ответы:

9

Вы можете просто и легко вызвать метод статической страницы из JavaScript, как в этом примере . Если вам нужно вызвать метод с нескольких страниц, вы можете настроить веб-сервис и вызвать его из Javascript таким же образом. Пример также включен ниже.

.aspx код

<asp:ScriptManager ID="ScriptManager1" 
EnablePageMethods="true" 
EnablePartialRendering="true" runat="server" />

Код за кодом

using System.Web.Services;

[WebMethod]
public static string MyMethod(string name)
{
    return "Hello " + name;
}

Код JavaScript

function test() {
    alert(PageMethods.MyMethod("Paul Hayman"));
}

ПРИМЕЧАНИЕ. Методы страницы должны быть статическими. Это может быть проблематично для вас, в зависимости от того, что пытается сделать приложение. Однако, если информация вообще основана на сеансе, и вы используете какую-то встроенную аутентификацию, вы можете поместить атрибут EnableSession в декоратор WebMethod, и это позволит вам получить доступ к HttpContext.Current.User, Сессия и т. Д.

Кейси Спикман
источник
Отличный пример, это хорошо работает, и я буду использовать его. Благодарность!
Маусимо
3

Я бы порекомендовал взглянуть на jQuery. JQuery может использоваться для выполнения обратных вызовов AJAX на сервер, который может передавать данные в любом нужном формате - хорошим форматом может быть JSON, поскольку он может использоваться непосредственно в javascript.

Чтобы получить данные с сервера в javascript с помощью jQuery , следующие выборки делают асинхронный запрос к http://youserver.com/my/uri и получают данные с сервера в предоставленной функции.

$.get("my/uri", 
    function(data) { 
       // client side logic using the data from the server
    })

Отправка данных из javascript на сервер работает аналогично:

$.post("my/uri", { aValue : "put any data for the server here" }
    function(data) { 
       // client side logic using the data returned from the server
    })
Кристиан Хорсдал
источник
Спасибо, это здорово, но я имею в виду ситуации, когда обратная передача выполняется до того, как клиент знает, что отображать. Если «результат» достигается с помощью C #, как мне тогда «внедрить» его обратно к клиенту.
cwc1983
3

Microsoft внедрила UpdatePanelконтроль над Ajax, так что это, пожалуй, «стандартный» способ. Я лично не рекомендовал бы использовать его, хотя он не имеет ничего общего с богатым набором функций и контроля, который вы имеете при непосредственном использовании JavaScript.

Вот как я лично это делаю:

Создайте скрытые поля для любых значений на стороне клиента, которые вы хотите использовать при стандартной обратной передаче страницы (т. Е. Когда пользователь нажимает "Отправить")

<asp:HiddenField ID="selectedProduct" runat="server" />

В коде позади зарегистрируйте элементы управления, которые вы хотите использовать на стороне клиента.

    /* Register the controls we want to use client side */

    string js = "var productBox = document.getElementById('" + selectedProduct.ClientID + "'); ";
    js += "var macCodeBoxBE = document.getElementById('" + beMacCode.ClientID + "'); ";


    ClientScript.RegisterStartupScript(this.GetType(), "prodBox", js, true);

Используйте библиотеку javascript * для публикации / получения ajax, а затем используйте JavaScript для обновления страницы на основе ответа

$.get("../ajax/BTBookAppointment.aspx?dsl=" + telNumberBox.value + "&date=" + requiredDate.value + "&timeslot=" + ddTimeslot.value, function (response, status, xhr) {

    if (response.indexOf("not available") > -1) {
        loaderImage.src = "../images/cross.png"
        output.innerHTML = response;
    } });

Напишите отдельную страницу «ajax», которая переопределяет метод рендеринга для выполнения работы.

protected override void Render(HtmlTextWriter writer)
{
    if (string.IsNullOrEmpty(Request["mac"])) { return; }
    if (string.IsNullOrEmpty(Request["dsl"])) { return; }
    DataLayer.Checkers.BTmacCheckResponse rsp = DataLayer.Checkers.Foo.CheckMAC(Request["dsl"], Request["mac"]);

    writer.Write(rsp.Valid.ToString());
}

* Есть много библиотек на выбор, вы даже можете свернуть свои собственные. Я бы порекомендовал jQuery , он стабильный и имеет обширный набор функций.

Том Сквайрс
источник
8
Я почти уверен, что в аду есть специальное место для людей, которые строят такие фрагменты JavaScript на сервере, как этот
Raynos
1
@Raynos Нет ничего плохого в создании серверной части JavaScript.
Том Сквайр
2
если вы хотите, чтобы сервер что-то делал, вы отправляете HTTP-запрос (используя XHR) на разумный URI с разумными данными. Оттуда на HTTP-сервере будет знать, что с ним делать.
Райнос
НЕ НАДЕЛЯЙТЕ JS НА СТОРОНУ СЕРВЕРА. ЭТО ИДЕТ НА КЛИЕНТА. ПОСМОТРИТЕ НАЗВАНИЕ КОДА СТОРОНЫ КЛИЕНТА. Ой, заглушка-заглушка застряла.
SnowYetis
3

JSON - лучший практический способ выполнить задачу. Не смотрите на проблему как на переход между «C # и JavaScript». Такое мышление приводит к странностям кода, таким как то, что есть в оригинальном посте.

В более общем смысле, это просто передача объектов между клиентом и сервером независимо от языка. JSON отлично подходит для этой задачи, потому что он широко поддерживается и легко читается.

P.Brian.Mackey
источник
2

Чтобы установить тег ввода, который не требует asp на стороне сервера, вы можете использовать: (или <% #%> для привязки данных формы)

HTML:

<input type="hidden" value='<%= RandomValues %>' name="RANDOM_VALUES" />

управление asp:

<asp:HiddenField ID="RandomList" runat="server" />

чтобы получить значения при обратной передаче

Request.Form["RANDOM_VALUES"]

Если его, asp контролировать скрытый ввод, вы можете использовать

Request.Form[RandomList.UniqueID]

Отличная часть запроса Request.Form - если у вас есть несколько тегов с одинаковым атрибутом «name», результат будет возвращен в CSV.

MackPro
источник