我试图创建一个基本的ASP.NET应用程序,使用名为FatSecret Sharp的包装器调用Fatsecret API,但是当我尝试从我的JS调用服务器端方法时出现此错误脚本,我想确定如何成功使用此包装器来创建Web应用程序。
您会注意到来自包装器的API调用明确提到它是"同步",所以我假设发生错误的是什么,我只是不知道" #39;不知道为什么,或者如何使用Web应用程序成功使用该调用。
这是我的代码:
的Javascript
var jsonData;
function search() {
var element = document.getElementById("searchField")
var searchTerm = element.value;
callAJAX("FoodSearchExample", searchTerm);
}
function callAJAX(requestMethod, term) {
var pageMethod = "default.aspx/" + requestMethod;
$.ajax({
url: pageMethod,
data: JSON.stringify({ searchTerm : term }),
type: "POST",
contentType: "application/json",
dataType: "JSON",
timeout: 600000,
success: function (result) {
ajaxCallback(result.d);
},
error: function (xhr, status) {
alert(status + " - " + xhr.responseText);
}
});
return false;
}
function ajaxCallback(serverResponse) {
if (serverResponse !== "loadLocations") {
//jsonData = JSON.parse(serverResponse);
alert(serverResponse);
}
else
alert("error");
}
C#
namespace HELP_Testing
{
public partial class _default : System.Web.UI.Page
{
private static string consumerKey = "key (removed from question)";
private static string consumerSecret = "secret (removed from question)";
[WebMethod]
public static string FoodSearchExample(string searchTerm)
{
FoodSearch foodSearch = new FoodSearch(consumerKey, consumerSecret);
string str = "";
var response = foodSearch.GetResponseSynchronously(new FoodSearchRequest()
{
SearchExpression = searchTerm
});
List<Food> foods = new List<Food>();
if (response.HasResults)
{
Food f;
foreach (var food in response.foods.food)
{
f = new Food();
f.FoodId = food.food_id;
f.FoodType = food.food_type;
f.FoodName = food.food_name;
foods.Add(f);
}
}
else
Console.WriteLine("No results from term");
JavaScriptSerializer serializer = new JavaScriptSerializer();
str = serializer.Serialize(foods);
return str;
}
protected void Page_Load(object sender, EventArgs e)
{
}
}
}
HTML
<%@ Page Language="C#" AutoEventWireup="true" Async="True" CodeBehind="default.aspx.cs" Inherits="HELP_Testing._default" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<script type="text/javascript" src="scripts/default.js"></script>
<script type="text/javascript" src="scripts/jquery-1.11.1.js"></script>
<title>Healthy Eating Life Planner</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<input type="text" name="Food Search" id="searchField" />
<button type="submit" onclick="search()">Search</button>
</div>
</form>
</body>
</html>
完整的错误消息是:
此时无法启动异步操作。异步操作只能使用异步处理程序或模块启动 或者在页面生命周期中的某些事件期间。如果在执行页面时发生此异常,请确保页面 被标记为Async = true。此例外还可能表示尝试调用“异步无效”空白&#39;方法,一般 ASP.NET请求处理中不受支持。相反,异步方法应该返回一个Task,调用者应该等待它#34;
答案 0 :(得分:1)
是的,the problem is in GetResponseSynchronously
。轮询完成是一个非常值得怀疑的方法。
有几种方法可以解决这个问题。一种是抛弃FatSearch CSharp库并使用HttpClient
写入他们的JSON API。这种方法更简洁,但意味着您必须编写更多代码。
另一种方法是wrap the sort-of-EBAP APIs from FatSearch CSharp as async
-compatible methods。在这种情况下,重要成员是GotResult
,GotError
和StartRequestAsync
。请注意,您的网络方法将变为async
。
答案 1 :(得分:0)
而不是打电话 公共任务GetResponseSynchronously(TRequest请求)就像示例控制台App建议的那样,在像MVC这样的Web上下文中,最好添加一个异步方法,比如我下面成功写的那个:
/// <summary>
/// Gets the response Asynchronously.
/// </summary>
/// <param name="request">The request.</param>
/// <returns>A parsed response, or throws an exception.</returns>
public async Task<TResponse> GetResponseAsynchronously(TRequest request)
{
var requestUrl = CreateRequestUrl(request);
HttpClient APIRequest = new HttpClient();
var response = await APIRequest.GetAsync(requestUrl).ConfigureAwait(false);
response.EnsureSuccessStatusCode();
string downloadedString = await response.Content.ReadAsStringAsync();
var result = ConvertClientResultString(downloadedString);
return result;
}
重要的是要注意,要获得无缝结果,您需要通过添加如下所示的响应处理方法来更改Service4u2Lib的BaseJsonService.c:
/// <summary>
/// Handles the client result string.
/// </summary>
/// <param name="downloadedString">The downloaded string.</param>
public TResultType ConvertClientResultString(string downloadedString)
{
// Check for html doctype and report error if found.
int takeLength = downloadedString.Length > 20 ? 20 : downloadedString.Length;
if (downloadedString.Substring(0, takeLength).Contains("!DOCTYPE html"))
HandleClientError(new NotSupportedException("The service call returned html and not json"));
var result = new TResultType();
string json = downloadedString;
if (result is IJSONMassager)
{
json = ((IJSONMassager)result).MassageJSON(downloadedString);
}
if (result is IJSONSelfSerialize<TResultType>)
{
result = ((IJSONSelfSerialize<TResultType>)result).SelfSerialize(json);
}
else
result = JsonHelper.Deserialize<TResultType>(json);
if (GotResult != null)
GotResult(this, new EventArgs<TResultType>() { Argument = result });
return result;
}
基本上我们重新调整现有对象,使它们可以使用HTTPClient对象,该对象可以使用.ConfigureAwait(false)处理请求。确保回调发生的方法。