Xamarin.Auth - "Произошла одна или несколько ошибок" с API мест Foursquare
Так что я в основном пробую что-то с API-интерфейсом Foursquare, но получаю странную ошибку всякий раз, когда отправляю запрос API.
Прежде всего я аутентифицируюсь с помощью следующего кода;
var foursquareClient = new FoursquareClient(this);
if(!foursquareClient.IsAuthenticated)
foursquareClient.Authenticate();`
Код аутентификации;
public void Authenticate()
{
Log.Verbose(Logging.AppTag, "FourSquareClient:Authenticate()");
if (this.IsAuthenticated)
{
Log.Debug(Logging.AppTag, "FourSquareClient is already authenticated! ");
return;
}
this._authenticator = new OAuth2Authenticator(
clientId: ClientId,
scope: "",
authorizeUrl: new Uri("https://foursquare.com/oauth2/authenticate"),
redirectUrl: new Uri("http://www.int6.org"))
{
AllowCancel = false
};
this._authenticator.Completed += (sender, eventArgs) =>
{
if (eventArgs.IsAuthenticated) // auth. completed.
{
this.StoreAccount(eventArgs);
var builder = new AlertDialog.Builder(this.OwnerContext);
builder.SetMessage("auth all good!");
builder.SetPositiveButton("Ok", (o, e) => { });
builder.Create().Show();
return;
}
else // The user cancelled.
{
var builder = new AlertDialog.Builder(this.OwnerContext);
builder.SetMessage("User canncelled!");
builder.SetPositiveButton("Ok", (o, e) => { });
builder.Create().Show();
return;
}
};
// show the authenticator UI and start auth.
var intent = this._authenticator.GetUI(this.OwnerContext);
this.OwnerContext.StartActivity(intent);
}
Таким образом, если пользователь прошел аутентификацию один раз, он сохранит учетную запись на устройстве.
public FoursquareClient(Context context)
{
Log.Verbose(Logging.AppTag, "Init foursquare client..");
this.OwnerContext = context; // make sure we set the owner context before any.
this.RetrieveAccount(); // try to retrieve any existing accounts.
}
Всякий раз, когда он открывает приложение снова, учетная запись будет загружена обратно;
private void RetrieveAccount()
{
if (this.IsAuthenticated)
{
Log.Debug(Logging.AppTag, "FourSquareClient is already authenticated! ");
return;
}
var accounts = AccountStore.Create(this.OwnerContext).FindAccountsForService("Foursquare");
var enumerable = accounts as IList<Account> ?? accounts.ToList();
if (enumerable.Any())
{
Log.Info(Logging.AppTag, "Foursquareclient found account data.");
this.IsAuthenticated = true;
this.Account = enumerable.First();
}
else
{
Log.Info(Logging.AppTag, "Foursquareclient no account data found!");
this.IsAuthenticated = false;
this.Account = null;
}
}
Так что я думаю, у меня все хорошо с аутентификацией, но почему-то не могу сделать запрос;
public string MakeRequest()
{
var @params = new Dictionary<string, string>
{
{"v", "20120321"},
{"ll", "44.3,37.2"}
};
var request = new OAuth2Request("GET", new Uri("https://api.foursquare.com/v2/venues/explore"), @params,
this.Account);
request.GetResponseAsync().ContinueWith(t =>
{
if (t.IsFaulted)
Console.WriteLine(t.Exception.Flatten());
else
{
string json = t.Result.GetResponseText();
Console.WriteLine(json);
}
});
return string.Empty;
}
Код запроса возвращается; Произошла одна или несколько ошибок
10-02 14:54:31.403 I/mono-stdout( 8641): System.AggregateException: произошла одна или несколько ошибок ---> System.Net.WebException: удаленный сервер возвратил ошибку: (400) неверный запрос. System.AggregateException: произошла одна или несколько ошибок ---> System.Net.WebException: удаленный сервер возвратил ошибку: (400) неверный запрос. 10-02 14: 54: 31.413 I / mono-stdout (8641): в System.Net.HttpWebRequest.CheckFinalStatus (результат System.Net.WebAsyncResult) [0x00000] в: 0 в System.Net.HttpWebRequest.CheckFinalStatus (System. Результат Net.WebAsyncResult) [0x00000] в: 0 в System.Net.HttpWebRequest.SetResponseData (данные System.Net.WebConnectionData) [0x00000] в:0 10-02 14:54:31.413 I/mono-stdout( 8641): в System.Net.HttpWebRequest.SetResponseData (данные System.Net.WebConnectionData) [0x00000] в:0 10-02 14:54:31.413 I/mono-stdout( 8641): --- Конец трассировки стека внутренних исключений - - --- Конец внутренней трассировки стека исключений -- --> (Внутреннее исключение 0) System.Net.WebException: удаленный сервер возвратил ошибку: (400) Bad Request. 10-02 14:54:31.423 I/mono-stdout( 8641): -> (внутреннее исключение 0) System.Net.WebException: удаленный сервер возвратил ошибку: (400) неверный запрос. 10-02 14: 54: 31.423 I / mono-stdout (8641): в System.Net.HttpWebRequest.CheckFinalStatus (результат System.Net.WebAsyncResult) [0x00000] в: 0 в System.Net.HttpWebRequest.CheckFinalStatus (System. Результат Net.WebAsyncResult) [0x00000] в: 0 10-02 14: 54: 31,423 I / mono-stdout (8641): в System.Net.HttpWebRequest.SetResponseData (данные System.Net.WebConnectionData) [0x00000] в: 0 в System.Net.HttpWebRequest.SetResponseData (данные System.Net.WebConnectionData) [0x00000] в: 0
Есть идеи о том, что мне не хватает?
2 ответа
Я исправил проблему, используя RestSharp вместо этого;
// https://developer.foursquare.com/docs/venues/explore
public string GetVenues()
{
var @params = new Dictionary<string, string>
{
{"v", "20120321"},
{"ll", "44.3,37.2"}
};
var response = this.Request("venues/explore", @params);
return response;
}
private string Request(string endpoint, Dictionary<string, string> @params = null, HttpMethod httpMethod = HttpMethod.GET, bool userless = false)
{
var client = new RestClient("https://api.foursquare.com/v2/");
var request = new RestRequest(endpoint, Method.GET);
if (!userless)
{
// About userless requests - https://developer.foursquare.com/overview/auth.html - Some of our endpoints that don’t pertain to
// specific user information, such as venues search are enabled for userless access (meaning you don’t need to have a user auth your
// app for access). To make a userless request, specify your consumer key's Client ID and Secret instead of an auth token in the request URL.
request.AddParameter("oauth_token", this.Account.Properties["access_token"]);
}
if (@params != null)
{
foreach (var param in @params)
{
request.AddParameter(param.Key, param.Value);
}
}
var response = client.Execute(request);
var content = response.Content; // raw content as string
return content;
}
Я только что использовал ваш самый первый код, но добавил параметр "oauth_token" вручную, и он работает просто отлично:)
Мой код выглядит примерно так:
var @params = new Dictionary<string, string>
{
{"oauth_token", this.Account.Properties["access_token"]},
{"v", "20120321"},
{"ll", "44.3,37.2"}
};