Вызов ajax-запроса из бритвы asp.net - PullRequest
0 голосов
/ 16 января 2019

Как мне инициировать ajax-запрос (вызов действия контроллера) из представления бритвы, которое возвращает данные в формате JSON?

В данный момент после нажатия на ссылку действия в моем представлении бритвы страница отправляет запрос на публикацию, который перенаправляет страницу в / actionName, которого, конечно, не существует.

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

ShowEventLogs.cshtml

@{ ViewBag.Title = "Event Logs"; }
@model IEnumerable
<Application.Models.EventLogs>
<table id="data-table" class="table display responsive" style="width:100%">
   <thead class="thead-colored thead-light">
      <tr>
         <th>Time</th>
         <th>Scheme</th>
         <th>Serial Number</th>
         <th>Batch</th>
         <th>Exp Date</th>
         <th>Product Code</th>
         <th>Http Code</th>
         <th>Is Confirmed?</th>
         <th>Confirmation Date</th>
         <th>Verify Pack</th>
      </tr>
   </thead>
   <tbody>
      @foreach (var item in Model)
      {
      <tr>
         <td>@item.Timestamp</td>
         <td>@item.ProductCodeScheme</td>
         <td>@item.SerialNumber</td>
         <td>@item.Batch</td>
         <td>@item.ExpirationDate</td>
         <td>@item.ProductCode</td>
         <td>@item.HttpResponseCode</td>
         <td>@item.ConfirmedParsed</td>
         <td>@item.ConfirmedDate</td>
         if (@item.HttpResponseCode == "202")
         {
         <td class="text-secondary">@Html.ActionLink("Verify Pack", "VerifyPack", "Home", new { ProductCodeScheme = @item.ProductCodeScheme, ProductCode = @item.ProductCode, SerialNumber = @item.SerialNumber, Batch = @item.Batch, ExpirationDate = @item.ExpirationDate, CommandStatusCode = 0 }, new { @class = "text-info" })</td>
         }
         else
         {
         <td class="text-secondary">Not Available</td>
         }
      </tr>
      }
   </tbody>
</table>
}

Действие контроллера

[HttpPost]
public ActionResult VerifyPack(string productCodeScheme, string productCode, string serialNumber, string batch, string expirationDate, int commandStatusCode, string orderTrackingNo = null) {
    string TextAreaResult = string.Empty;
    string TextAreaResultException = string.Empty;
    string TextAreaResultHttpOperationCode = string.Empty;
    string TextAreaResultHttpResponseCode = string.Empty;
    string TextAreaResultHttpInformation = string.Empty;
    string TextAreaResultHttpWarning = string.Empty;
    string TextAreaResultState = string.Empty;
    string RemoteIpAddress = string.Format("{0}", Request.UserHostAddress);

    try {
        using(SecureMediDatabase database = new SecureMediDatabase(this)) {
            DatabaseFactory.setDatabase(database);
            Request baseRequest = (Request) database.createRequest(Country);
            ServiceThread serviceThread = new ServiceThread(0, null, Country);
            serviceThread.attach(this);

            baseRequest.setId(0);
            baseRequest.setProductCodeScheme(productCodeScheme);
            baseRequest.setRequestType(1); //single pack
            baseRequest.setProductCode(productCode);
            baseRequest.setSerialNumber(serialNumber);
            baseRequest.setBatch(batch);
            baseRequest.setExpirationDate(expirationDate);
            baseRequest.setWorkstation(RemoteIpAddress);
            baseRequest.setManualEntry(string.IsNullOrEmpty(expirationDate) || string.IsNullOrEmpty(batch));

            if (baseRequest.isManualEntry()) {
                switch (commandStatusCode) {
                    case 2:
                    case 3:
                        break;

                    default:
                        throw new NotSupportedException("This operation does not support manual entries!");
                }
            }

            switch (Country) {
                case "SE":
                    SecureMediRequestSE requestSE = (SecureMediRequestSE) baseRequest;
                    requestSE.setUserId(@User.Identity.Name);
                    requestSE.setCommandStatusCode(commandStatusCode);
                    requestSE.OrderTrackingNumber = orderTrackingNo;
                    break;

                case "FI":
                    SecureMediRequestFI requestFI = (SecureMediRequestFI) baseRequest;
                    requestFI.setSubUserId(@User.Identity.Name);
                    break;
            }

            serviceThread.RunRequest(control, baseRequest, apteekki);

            TextAreaResult = string.Format("{0} {1} {2} {3} {4}", baseRequest.getResponseOperationCode(), baseRequest.getHttpResponseCode(), baseRequest.getHttpInformation(), baseRequest.getHttpWarning(), baseRequest.getResponseStatusCode());

            TextAreaResultHttpOperationCode = string.Format("{0}", baseRequest.getResponseOperationCode());

            TextAreaResultHttpResponseCode = string.Format("{0}", baseRequest.getHttpResponseCode());

            TextAreaResultHttpInformation = string.Format("{0}", baseRequest.getHttpInformation());

            TextAreaResultHttpWarning = string.Format("{0}", baseRequest.getHttpWarning());

            TextAreaResultState = string.Format("{0}", baseRequest.getResponseStatusCode());
        }
    } catch (Exception exc) {
        TextAreaResultException = "Exception: " + exc.Message;
    }

    return Json(new {
        result = TextAreaResult,
        httpOperationCode = TextAreaResultHttpOperationCode,
        httpResponseCode = TextAreaResultHttpResponseCode,
        httpInformation = TextAreaResultHttpInformation,
        httpWarning = TextAreaResultHttpWarning,
        state = TextAreaResultState,
        exception = TextAreaResultException,
        isSuccess = TextAreaResultHttpResponseCode == "200" || TextAreaResultHttpResponseCode == "202"
    });
}

Ошибка на основе ответа:

enter image description here enter image description here

Ответы [ 2 ]

0 голосов
/ 16 января 2019

В основном @Html.ActionLink() помощник отображает тег привязки (<a>) с атрибутами и по умолчанию использует запрос GET, обновляя всю страницу, поэтому вам необходимо добавить preventDefault() для использования обратного вызова AJAX из этого элемента. Если в методе действия используется метод HTTP GET, вы можете выполнить простой вызов AJAX для общего класса якорной ссылки, например:

$('.text-info').on('click', function (e) {
    e.preventDefault();

    var url = $(this).attr('href');
    $.get(url, function (response) {
        // do something with AJAX response
    });
});

Однако, поскольку целевое действие контроллера помечено как [HttpPost], вам необходимо извлечь параметры строки запроса из атрибута href с помощью дополнительной функции и использовать их в вызове AJAX с настройкой type: 'POST' или использовать $.post():

$('.text-info').on('click', function (e) {
    e.preventDefault(); // mandatory to prevent GET request

    var url = $(this).attr('href');

    var pcs = getQueryStringParams(url, 'ProductCodeScheme');
    var pc = getQueryStringParams(url, 'ProductCode');
    var sn = getQueryStringParams(url, 'SerialNumber');
    var batch = getQueryStringParams(url, 'Batch');
    var expDate = getQueryStringParams(url, 'ExpirationDate');
    var csc = getQueryStringParams(url, 'CommandStatusCode');

    // create key-value pair for action method parameters
    var obj = { ProductCodeScheme: pcs, ProductCode: pc, SerialNumber: sn, ... }

    $.ajax({
        type: 'POST',
        url: url.split('?')[0], // URL without query string, or use '@Url.Action("VerifyPack", "Home")'
        data: obj,
        dataType: 'json', // expects response as JSON
        success: function (response) {
            // do something with AJAX response
        },
        error: function (xhr, status, err) {
            // error handling
        }
    });

    // just make sure that the link is not redirecting
    return false;
});

function getQueryStringParams(url, name) {
     return (RegExp(name + '=' + '(.+?)(&|$)').exec(url)||[,null])[1];
}

На самом деле существует другой способ вызова AJAX из тега привязки, например @Ajax.ActionLink(), в зависимости от вашего выбора:

@Ajax.ActionLink("Verify Pack", "VerifyPack", "Home", new { ProductCodeScheme = @item.ProductCodeScheme, ProductCode = @item.ProductCode, SerialNumber = @item.SerialNumber, Batch = @item.Batch, ExpirationDate = @item.ExpirationDate, CommandStatusCode = 0 }, 
                 new AjaxOptions { HttpMethod = "POST", 
                                   InsertionMode = InsertionMode.Replace, 
                                   UpdateTargetId = "targetElementId", 
                                   OnComplete = "onComplete();" 
                                 },
                 new { @class = "text-info" })

Примечание:

Если вам нужно обработать AJAX-запрос и обычный запрос от одного и того же контроллера, вы можете различить их, используя Request.IsAjaxRequest() (или Context.Request.Headers["X-Requested-With"] == "XMLHttpRequest" в Core MVC).

0 голосов
/ 16 января 2019

Нечто подобное должно начать вас.Добавьте класс к элементам, из которых вам нужно получить информацию.Тогда вместо использования actionlink просто создайте обычный элемент с уникальным классом.Пусть JQuery обрабатывает события щелчка по этим ссылкам и передает другие элементы TD той же строки контроллеру с помощью вызова AJAX.

$(".button").click( function() {
	var tr = $(this).closest("tr");
  var ProductCodeScheme = tr.find(".ProductCodeScheme").html();
  var SerialNumber = tr.find(".SerialNumber").html();
  var Batch = tr.find(".Batch").html();
  var ExpirationDate = tr.find(".ExpirationDate").html();
  var ProductCode = tr.find(".ProductCode").html();
  
  $.ajax({
    url: "/Verify Pack/VerifyPack", 
    type: "POST",      
    data: ({
    	ProductCodeScheme: ProductCodeScheme,
      SerialNumber: SerialNumber,
      Batch: Batch,
      ExpirationDate: ExpirationDate,
      ProductCode: ProductCode
    }),     
    cache: false,
    success: function(data){                          
      //Do something here for a successful POST                   
    }           
  });    
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table id="data-table" class="table display responsive" style="width:100%">
   <thead class="thead-colored thead-light">
      <tr>
         <th>Time</th>
         <th>Scheme</th>
         <th>Serial Number</th>
         <th>Batch</th>
         <th>Exp Date</th>
         <th>Product Code</th>
         <th>Http Code</th>
         <th>Is Confirmed?</th>
         <th>Confirmation Date</th>
         <th>Verify Pack</th>
      </tr>
   </thead>
   <tbody>
      <tr>
         <td>Timestamp 1</td>
         <td class="ProductCodeScheme">ProductCodeScheme 1</td>
         <td class="SerialNumber">SerialNumber 1</td>
         <td class="Batch">Batch 1</td>
         <td class="ExpirationDate">ExpirationDate 1</td>
         <td class="ProductCode">ProductCode 1</td>
         <td>HttpResponseCode 1</td>
         <td>ConfirmedParsed 1</td>
         <td>ConfirmedDate 1</td>
         <td class="text-secondary"><a href="#!" class="button">Item 1</a></td>
      </tr>
     <tr>
         <td>Timestamp 2</td>
         <td class="ProductCodeScheme">ProductCodeScheme 2</td>
         <td class="SerialNumber">SerialNumber 2</td>
         <td class="Batch">Batch 2</td>
         <td class="ExpirationDate">ExpirationDate2</td>
         <td class="ProductCode">ProductCode 2</td>
         <td>HttpResponseCode 2</td>
         <td>ConfirmedParsed 2</td>
         <td>ConfirmedDate 2</td>
         <td class="text-secondary"><a href="#!" class="button">Item 2</a></td>
      </tr>
   </tbody>
</table>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...