Не могу получить обещание в Blazor - PullRequest
1 голос
/ 05 мая 2019

Я делаю POST запрос от Blazor к серверу через js interop. Почтовый запрос попадает на сервер, вычисляется, отправляется обратно. Обработчик js вызывает обещание resolve, но данные не возвращаются к Blazor.

JS Interop

window.methods={
    submit: function () {
            return new Promise((resolve, reject) => {
                var form = document.getElementById("newTestForm");
                var data = new FormData(form);
                var xhr = new XMLHttpRequest();


                var method = form.getAttribute('method');
                var action = form.getAttribute('action');
                xhr.open(method, action);
                xhr.onload = function () {
                    if (xhr.status == 200) {
                        resolve(xhr.response); //data gets here in correct format !!!!!!!
                    }
                    else if (xhr.status != 200) {
                        reject("Failed to submit form with status" + xhr.status);
                    }
                }
                xhr.send(data);
            });
        }
}

Контроллер

[HttpPost]
[Route("/myroute")]
public async Task<string> ReturnData()
{
    await Task.Delay(1000);
    return "hello";
}

Компонент Blazor

<form method="post" action="/myroute">
....some inputs
</form>
<button onclick="@SubmitAsync"></button>
@functions{
      public static async Task<string> SubmitNewTestAsync()
        {
            try
            {
                var data = await JSRuntime.Current.InvokeAsync<string>("methods.submit");

                return data;
            }
            catch (Exception ex)
            {

                throw;
            }

        }

     public async Task SubmitAsync()
     {
         string data= await SubmitNewTestAsync();
     }
}

Ответ правильный, а метод js submit вызывает resolve в результате. Сначала я подумал, что это может быть проблемой десериализации. Но это не выдает никакой ошибки.

Я пробовал с различными типами ответа (bytes, objects, string), и до сих пор нет ни ответа, ни исключения.

В чем может быть проблема?

P.S Мне нужно использовать XMLHttpRequest, так как я хочу остаться на той же странице. Я должен увидеть исключения, если они существуют в Blazor, так как я тестирую с использованием Server-Side hosting

Обновление

Итак, после многих попыток проблема, похоже, на стороне Blazor, особенно в методе JSRuntime.Current.InvokeAsync<Type>.
Кажется, что запрос просто завершит , не возвращая что-либо (и при этом не выдает ничего ошибка), если Type не является primitive / object / dynamic. Я не знаю, если это больше Blazor специфическая проблема.

Пример * +1057 *

Учитывая следующую модель:

[Serializeable]
public class MyType{
 public int value{get;set;}
}

Так вот что происходит (сторона Блазора):

var data = await JSRuntime.Current.InvokeAsync<MyType>("methods.submit"); //fails
var data = await JSRuntime.Current.InvokeAsync<object>("methods.submit"); //works
var data = await JSRuntime.Current.InvokeAsync<dynamic>("methods.submit"); //works

До сих пор тестировались также с long, int и string, и они работают. Кажется, нет проблем с получением примитивов.

1 Ответ

2 голосов
/ 06 мая 2019

Это может быть результатом использования статического свойства JSRuntime.Current, которое было удалено.Вместо этого вы должны вставить IJSRuntime в ваш компонент следующим образом:

@ inject IJSRuntime JSRuntime;

public static async Task<string> SubmitNewTestAsync()
    {
        try
        {
            var data = await JSRuntime.InvokeAsync<string>("methods.submit");

            return data;
        }
        catch (Exception ex)
        {

            throw;
        }

    }

Попробуйте этот фрагмент кода в вашей функции JavaScript:

xhr.onload = function () {
      if (this.status >= 200 && this.status < 300) {
        resolve(xhr.responseText);
      } else {
         reject("Failed to submit form with status" + xhr.status);
      }
    };
...