2015-02-13 2 views
0

Я использую оболочку Furl.Http поверх .NET Http Client. С каждым запросом мой API требует отправки User-Agent и заголовка авторизации.Как сохранить заголовки в Flurl HttpClient

Я хотел бы установить это один раз, вместо того, чтобы говорить об этом каждый раз.

То, что я думал, что я мог бы сделать, это создать экземпляр FlurlClient и установить заголовки на нем, а затем ResetToRoot перед каждым запросом, как показано в этом примере фрагмент кода:

var fc = new FlurlClient(); 
    fc.WithHeader("User-Agent", "Keep/1.0"); 
    var tokenModel = await 
     "https://app.tempuri.com".AppendPathSegment("auth") 
     .WithClient(fc) 
     .PostUrlEncodedAsync(new { username = "you", password = "secret"}) 
     .ReceiveJson<TokenModel>(); 

    fc.WithHeader("Authorization", 
     string.Format("Token {0}",tokenModel.Token));     

fc.Url.ResetToRoot(); 
    var userModel = await fc.Url 
          .AppendPathSegment("auth").GetJsonAsync<UserModel>(); 
    Console.WriteLine(userModel.Username); 

Однако оказалось, что после RestToRoot() заголовки больше не отправляются.

Это по дизайну? Есть ли лучший подход к страхованию этих заголовков, отправляемых по каждому запросу?

ответ

1

Проблема является второй по последней строке.

fc.Url...GetJsonAsync 

FlurlClient имеет ссылку на Url объекта, но не наоборот, так что к тому времени, когда вы звоните fc.Url, вы фактически потеряли, что ссылка и новый FlurlClient создается за сценой, когда вы звоните GetJsonAsync , Это по дизайну в том, что Flurl.Url - это простой класс строителя в основной библиотеке Flurl, который может использоваться независимо от Flurl.Http.

Вот как я это сделать:

var url = "https://app.tempuri.com"; 

using (var fc = new FlurlClient().WithHeader("User-Agent", "Keep/1.0")) { 
    var tokenModel = await url 
     .AppendPathSegment("...") 
     .WithClient(fc) 
     .PostUrlEncodedAsync(new { username = "you", password = "secret"}) 
     .ReceiveJson<TokenModel>(); 

    fc.WithHeader("Authorization", 
     string.Format("Token {0}",tokenModel.Token));     

    var userModel = await url 
     .AppendPathSegment("...") 
     .WithClient(fc) 
     .GetJsonAsync<UserModel>(); 

    Console.WriteLine(userModel.Username); 
} 

Пара отмечает:

  1. Извещение вы прикреплениеFlurlClient в каждом HTTP-вызова.
  2. Здесь переменная url является просто строкой, поэтому нет необходимости звонить ResetToRoot.
  3. Заявление using здесь совершенно не обязательно, но это хорошая практика.
1

Существует и альтернативный подход, который тоже сработает. Для каждого последующего HTTP вызова, изменить fc.Url первый, а затем использовать fc, чтобы сделать вызов:

fc.Url.ResetToRoot().AppendPathSegment(...); 
var x = await fc.GetJsonAsync<T>(); 

В этом случае вам нужно будет позвонить ResetToRoot, но не WithClient. Свободная цепь здесь сломана, но вы можете найти ее более читаемой. В любом случае, это только вопрос личных предпочтений.

Смежные вопросы