3

XamarinプロジェクトでSimple.OData.Clientを使用する前に、 LINQPadを使用して試してみました。とても使いやすくて感動しました。Xamarinプロジェクトに組み込むと、 SharePointの REST Apiからデータを取得しようとして例外が発生しました。

Simple.OData.Client.WebRequestException: 予期しない WebException が発生しました ---> System.Net.WebException: エラー: SendFailure (ヘッダーの書き込みエラー) ---> System.Net.WebException: ヘッダーの書き込みエラー ---> System.IO. IOException: 認証または decr...{Simple.OData.Client.WebRequestException: 予期しない WebException が発生しました ---> System.Net.WebException: エラー: SendFailure (ヘッダーの書き込みエラー) ---> System.Net.WebException: エラーヘッダーの書き込み ---> System.IO.IOException: 認証または復号化に失敗しました。---> Mono.Security.Protocol.Tls.TlsException: サーバーから無効な証明書を受け取りました。エラー コード: 0xffffffff800b010a

私が信じているように、この例外は、SharePointインスタンスが自己署名証明書を使用していることが原因でした。ServerCertificateValidationCallbackに常に true を返すことで排除しようとしました

System.Net.ServicePointManager.ServerCertificateValidationCallback = (sender, certificate, chain, errors) => true;

今では、Simple.OData.Client からUnauthorized例外が常に発生します。

Simple.OData.Client.WebRequestException: 権限がありません

最初の呼び出しはMainViewModelからビジネス レイヤーを介して行われます

    private async void InitializeAsync()
    {
        // TODO [Anton Kalcik - Dienstag, 05. Mai 2015 17:09:55]: Show loading indicator
        TaskEntity getTaskForCurrentMonthAsyncTask = await _taksBusinessLayer.GetTaskForCurrentMonthAsync();
        _timeToDisplay = getTaskForCurrentMonthAsyncTask.DueDate - DateTime.Now;
        // TODO [Anton Kalcik - Dienstag, 05. Mai 2015 17:10:04]: Hide loading indicator

        StartCountdownTimer();
    }

呼び出しを実行するクラスはクラスSharePointTaskRepositoryです

public class SharePointTaskRepository : ITaskRepository
{
    private readonly string _collectionName;
    private readonly ODataClient _oDataClient;

    public SharePointTaskRepository(Uri sharepointUri, string collectionName, ICredentials credentials)
    {
        if (sharepointUri == null)
        {
            throw new ArgumentNullException("sharepointUri");
        }
        if (String.IsNullOrWhiteSpace(collectionName))
        {
            throw new ArgumentException("Argument can't be null, empty or white space!", "collectionName");
        }
        if (credentials == null)
        {
            throw new ArgumentNullException("credentials");
        }

        _collectionName = collectionName;

        var oDataClientSettings = new ODataClientSettings(sharepointUri, credentials);
        _oDataClient = new ODataClient(oDataClientSettings);
    }

    public async Task<IEnumerable<TaskModel>> ReadAsync(Expression<Func<TaskModel, bool>> filter, Expression<Func<TaskModel, object>> orderBy, int numberOfResults)
    {
        return await _oDataClient
                    .For<TaskModel>(_collectionName)
                    .Filter(filter)
                    .OrderBy(orderBy)
                    .Top(numberOfResults)
                    .FindEntriesAsync();
    }
}

資格情報を再確認しましたが、間違いなく正しいです。ServerCertificateValidationCallbackを利用するコードはApplicationRuntimeSettingsにあります。このクラスはプラットフォーム固有のシングルトンであり、依存性注入によって他のすべてのオブジェクトとして提供されます。

[assembly: Dependency(typeof(ApplicationRuntimeSettings))]
namespace AZeitReminder.Droid.Infrastructure
{
    public class ApplicationRuntimeSettings : ApplicationRuntimeSettingsBase
    {
        public ApplicationRuntimeSettings()
        {
            System.Net.ServicePointManager.ServerCertificateValidationCallback = (sender, certificate, chain, errors) => true;
        }

        public override SQLiteConnection CreateSqLiteConnection()
        {
                string documentsPath = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
                var path = Path.Combine(documentsPath, DatabaseFileName);
                var currentPlatform = new SQLitePlatformAndroid();
                var connection = new SQLiteConnection(currentPlatform, path);

                return connection;
        }

        public override CultureInfo GetCultureInfo()
        {
            var androidLocale = Java.Util.Locale.Default;
            var netLanguage = androidLocale.ToString().Replace("_", "-"); // NOTE [Anton Kalcik - Dienstag, 05. Mai 2015 17:21:10]: turns pt_BR into pt-BR
            return new CultureInfo(netLanguage);
        }
    }
}
4

1 に答える 1

1

PreAuthenticate = false; を設定してみることができます。あなたの要求のために。Simple.ODataClient は内部で HttpClientHandler を使用します。この HttpClientHandler は PreAuthenticate = true; を設定します。ただし、OnApplyClientHandler でこのハンドラーを変更して、プロパティを false に設定できます。コードでこれを試してください:

oDataClientSettings.OnApplyClientHandler = handler => handler.PreAuthenticate = false;

その理由は、Sharepoint サーバーがチャレンジ応答として「Unauthorized」をスローする可能性があり、このプロパティが false でない限り WebRequest がチャレンジに応答しないためです。

于 2015-05-06T11:37:32.290 に答える