Основная страница бритвы asp.net вызывает службу отдыха и как ждать ответа. - PullRequest
0 голосов
/ 30 ноября 2018

У меня есть страница бритвы, которая вызывает службу отдыха, чтобы найти геокоды для указанного адреса.Вызов использует обратный вызов, вызванный событием, когда он завершает поиск.Все работает, но время выключено.К тому времени, когда обратный вызов заканчивается, страница уже прорисована, и мне нужны результаты обратного вызова, чтобы правильно нарисовать страницу.

using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Options;
using Northwind.ModelsDB;
using System.Runtime.Serialization.Json;
using BingMapsRESTToolkit;
using System.Net;

namespace Northwind.Pages.CustomerPages
{

public class DetailsModel : PageModel
{
  private readonly Northwind.ModelsDB.NorthwindContext _context;
  private readonly IOptions<MyConfig> config;
  public string BingMapKey { get; private set; }
  public double latitude { get; private set; }
  public double longitude { get; private set; }
  public string query { get; private set; }
  public VIndividualCustomer VIndividualCustomer { get; private set; }

  public DetailsModel(Northwind.ModelsDB.NorthwindContext context, IOptions<MyConfig> configg)
  {
     _context = context;
     this.config = configg;
     BingMapKey = config.Value.BingMapKey;
  }

  public async Task<IActionResult> OnGetAsync(int? id)
  {
     if (id == null)
     {
        return NotFound();
     }

     VIndividualCustomer = await _context.VIndividualCustomer
        .AsNoTracking()
        .FirstOrDefaultAsync(m => m.BusinessEntityId == id);

     if (VIndividualCustomer == null)
     {
        return NotFound();
     }

     query = VIndividualCustomer.AddressLine1 + " " +
        VIndividualCustomer.AddressLine2 + ", " +
        VIndividualCustomer.City + ", " +
        VIndividualCustomer.StateProvinceName + ", " +
        VIndividualCustomer.PostalCode;
     query = "1 Microsoft Way, Redmond, WA";
     Uri geocodeRequest = new Uri(string.Format("http://dev.virtualearth.net/REST/v1/Locations?q={0}&key={1}", query, BingMapKey));
     GetResponse(geocodeRequest, (x) =>
     {
        var location = (BingMapsRESTToolkit.Location)x.ResourceSets[0].Resources[0];
        latitude = location.GeocodePoints[0].Coordinates[0];
        longitude = location.GeocodePoints[0].Coordinates[1];
     });

     return Page();
  }

  private void GetResponse(Uri uri, Action<Response> callback)
  {
     System.Net.WebClient wc = new WebClient();
     wc.OpenReadCompleted += (o, a) =>
     {
        if (callback != null)
        {
           DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(Response));
           callback(ser.ReadObject(a.Result) as Response);
        }
     };
     wc.OpenReadAsync(uri);


  }

}}

Ответы [ 2 ]

0 голосов
/ 30 ноября 2018

Самым закрытым кодом для вашего собственного кода является этот фрагмент:

    private async Task GetResponseAsync(Uri uri, Action<Response> callback) {
        System.Net.Http.HttpClient wc = new HttpClient();
        var response = await wc.GetAsync(uri);
        if (callback != null) {
            var stream = await response.Content.ReadAsStreamAsync();
            DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(Response));
            callback(ser.ReadObject(stream) as Response);
        }
    }

и назовите его так:

 await GetResponse(geocodeRequest, (x) =>
 {
    / bla bla bla...
 });

Однако это не очень хороший рефакторинг кода.Но могу сделать работу.

0 голосов
/ 30 ноября 2018

Ваш метод никогда не будет обновлен, потому что ответ уже отправлен клиенту.Вам необходимо заблокировать метод (используйте вместо него HttpClient) и дождаться ответа:

public async Task<IActionResult> OnGetAsync(int? id)
{
  // this "reads" better
  if (id.HasValue)
  {
    return NotFound();
  }

  VIndividualCustomer = await _context.VIndividualCustomer
    .AsNoTracking()
    .FirstOrDefaultAsync(m => m.BusinessEntityId == id);

  if (VIndividualCustomer == null)
  {
    return NotFound();
  }

  query = VIndividualCustomer.AddressLine1 + " " +
    VIndividualCustomer.AddressLine2 + ", " +
    VIndividualCustomer.City + ", " +
    VIndividualCustomer.StateProvinceName + ", " +
    VIndividualCustomer.PostalCode;
  query = "1 Microsoft Way, Redmond, WA";

  // string interpolation
  //https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/tokens/interpolated
  var url = $"http://dev.virtualearth.net/REST/v1/Locations?q={query}&key={BingMapKey}";
  var geocodeRequest = new Uri(url);

  var ser = new DataContractJsonSerializer(typeof(Response));

  var response = await (new HttpClient()).GetAsync(geocodeRequest);
  var json = await response.Content.ReadAsStringAsync();
  var x = ser.ReadObject(json) as Response;     

  var location = (BingMapsRESTToolkit.Location)x.ResourceSets[0].Resources[0];
  latitude = location.GeocodePoints[0].Coordinates[0];
  longitude = location.GeocodePoints[0].Coordinates[1];

  return Page();
}
...