我有一个剃须刀页面,该页面调用休息服务以查找所提供地址的地理编码。该调用在完成查找时将使用事件触发的回调。一切正常,但时机已到。到回调完成时,页面已经绘制完毕,我需要回调的结果才能正确绘制页面。
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);
}
} }
答案 0 :(得分:1)
您的方法将永远不会更新,因为响应已发送到客户端。您需要阻止该方法(改为使用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();
}
答案 1 :(得分:0)
与您自己的代码最接近的代码是以下代码段:
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...
});
但是,这不是一个好的重构代码。但是可以做到的。