Showing posts with label Web service. Show all posts
Showing posts with label Web service. Show all posts

Wednesday, February 17, 2021

Get list items from Sharepoint using lists.asmx web service

In one of my previous articles I showed how to get authentication cookies (FedAuth) from Sharepoint FBA using authentication.asmx web service (see Authenticate in Sharepoint on-prem FBA site via OTB /_vti_bin/Authentication.asmx web service). In this post I will show how to use these cookies and get list items from Sharepoint list using standard lists.asmx web service.

It can be done using the following code:

Cookie authCookies = ...;
string listTitle = ...;
string soapBody =
	"<soap:Envelope xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/'>" +
	"  <soap:Body>" +
	"    <GetListItems xmlns='http://schemas.microsoft.com/sharepoint/soap/'>" +
	"      <listName>" + listTitle + "</listName>" +
	"    </GetListItems>" +
	"  </soap:Body>" +
	"</soap:Envelope>";
var cookies = new CookieContainer();
cookies.Add(authCookies);
var handler = new HttpClientHandler();
handler.CookieContainer = cookies;
using (var httpClient = new HttpClient(handler))
{
	var req = new HttpRequestMessage(HttpMethod.Post, "http://example.com/_vti_bin/lists.asmx")
	{
		Content = new StringContent(soapBody, Encoding.UTF8, "text/xml")
	};
	var res = httpClient.SendAsync(req).GetAwaiter().GetResult();
	string result
	if (res.StatusCode == HttpStatusCode.OK)
	{
		result = res.Content.ReadAsStringAsync().Result;
	}
}

Here we use auth cookies from previous article. We again create special SOAP body where pass list title. In this example we will get all list items but it is also possible to fetch list items which match CAML query - for that you will need to use quert, viewFieldsm rowLimit and queryOptions tags in SOAP body. For more information about these properties refer to documentation of lists.asmx web service. Id everything was done correctly it will return you list items from specified lists in SOAP format.

Tuesday, January 26, 2021

Authenticate in Sharepoint on-prem FBA site via OTB /_vti_bin/Authentication.asmx web service

Sharepoint contains number of OTB web services which are located inside _vti_bin virtual directory. In this article we will check one of them: authentication.asmx. This is quite interesting web service which allows to authenticate your app in Sharepoint FBA site. I.e. allows to send username and password and get FedAuth authentication cookies if provided credentials are valid (the same cookies which are used by Sharepoint FBA site when you successfully logged in via it’s login page).

Note that you may use this web service in server-side apps or mobile apps but not in client side JavaScript-based solution because FedAuth cookies have HttpOnly flag and thus can’t be used in JavaScript.

In order to use this web service we need to send special SOAP body in HTTP POST request. In order to get example of this SOAP open http://example.com/_vti_bin/authentication.asmx in browser (where instead of http://example.com you should use url of your site). It will show list of available web methods:

  • Login
  • Mode

Click on Login and you will get needed SOAP examples (in this article we will use SOAP 1.1):

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Body>
    <Login xmlns="http://schemas.microsoft.com/sharepoint/soap/">
      <username>string</username>
      <password>string</password>
    </Login>
  </soap:Body>
</soap:Envelope>

In this SOAP body we need to set actual username and password in appropriate xml tags.

Here is example which shows how to send this SOAP body to authentication.asmx web service and get authentication cookies:

var cookies = new CookieContainer();
var handler = new HttpClientHandler();
handler.CookieContainer = cookies;
using (var httpClient = new HttpClient(handler))
{
    string soapBody =
    "<soap:Envelope xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/'>" +
    "  <soap:Body>" +
    "    <Login xmlns='http://schemas.microsoft.com/sharepoint/soap/'>" +
    "      <username>" + username + "</username>" +
    "      <password>" + password + "</password>" +
    "    </Login>" +
    "  </soap:Body>" +
    "</soap:Envelope>";
    var req = new HttpRequestMessage(HttpMethod.Post, "http://example.com/_vti_bin/authentication.asmx");
    req.Content = new StringContent(soapBody, Encoding.UTF8, "text/xml")
    var res = httpClient.SendAsync(req).GetAwaiter().GetResult();
    if (res.StatusCode == HttpStatusCode.OK)
    {
        var response = res.Content.ReadAsStringAsync().Result;
        var cookie = cookies.GetCookies(new Uri("http://example.com")).Cast<Cookie>().FirstOrDefault(c => c.Name == "FedAuth");
    }
}

In this example we first create HTTP POST request to authentication.asmx using SOAP body retrieved above and then if authentication was successful read FedAuth cookies returned from server. After that we may use these cookies for making authenticated calls to other web services. In one of the future articles I will show how to do that.

Sunday, November 26, 2017

Real time currency conversion using web service for .Net

Sometimes you need to automatically convert currencies in the app. In order to do that you need to get current conversion ratios for appropriate currencies. There are many web services which provide this data: free and chargeable. In this post I will use free web service provided by Central bank of Russia, in your code you may use other services, e.g. service provided by Central European bank. There is convenient web service which returns currencies conversion ratios for the current day:

http://www.cbr.ru/scripts/XML_daily.asp?date_req=dd/MM/yyyy

E.g. if we want to get it for 26 Nov 2017 we need to use the following url:

http://www.cbr.ru/scripts/XML_daily.asp?date_req=26/11/2017

Here is result:

   1: <?xml version="1.0" encoding="windows-1251"?>
   2: <ValCurs Date="25.11.2017" name="Foreign Currency Market">
   3: <Valute ID="R01010">
   4:     <NumCode>036</NumCode>
   5:     <CharCode>AUD</CharCode>
   6:     <Nominal>1</Nominal>
   7:     <Name>Австралийский доллар</Name>
   8:     <Value>44,5778</Value>
   9: </Valute>
  10: <Valute ID="R01020A">
  11:     <NumCode>944</NumCode>
  12:     <CharCode>AZN</CharCode>
  13:     <Nominal>1</Nominal>
  14:     <Name>Азербайджанский манат</Name>
  15:     <Value>34,4609</Value>
  16: </Valute>
  17: <Valute ID="R01035">
  18:     <NumCode>826</NumCode>
  19:     <CharCode>GBP</CharCode>
  20:     <Nominal>1</Nominal>
  21:     <Name>Фунт стерлингов Соединенного королевства</Name>
  22:     <Value>77,9644</Value>
  23: </Valute>
  24: <Valute ID="R01060">
  25:     <NumCode>051</NumCode>
  26:     <CharCode>AMD</CharCode>
  27:     <Nominal>100</Nominal>
  28:     <Name>Армянских драмов</Name>
  29:     <Value>12,0933</Value>
  30: </Valute>
  31: <Valute ID="R01090B">
  32:     <NumCode>933</NumCode>
  33:     <CharCode>BYN</CharCode>
  34:     <Nominal>1</Nominal>
  35:     <Name>Белорусский рубль</Name>
  36:     <Value>29,2835</Value>
  37: </Valute>
  38: <Valute ID="R01100">
  39:     <NumCode>975</NumCode>
  40:     <CharCode>BGN</CharCode>
  41:     <Nominal>1</Nominal>
  42:     <Name>Болгарский лев</Name>
  43:     <Value>35,4717</Value>
  44: </Valute>
  45: <Valute ID="R01115">
  46:     <NumCode>986</NumCode>
  47:     <CharCode>BRL</CharCode>
  48:     <Nominal>1</Nominal>
  49:     <Name>Бразильский реал</Name>
  50:     <Value>18,1669</Value>
  51: </Valute>
  52: <Valute ID="R01135">
  53:     <NumCode>348</NumCode>
  54:     <CharCode>HUF</CharCode>
  55:     <Nominal>100</Nominal>
  56:     <Name>Венгерских форинтов</Name>
  57:     <Value>22,2428</Value>
  58: </Valute>
  59: <Valute ID="R01200">
  60:     <NumCode>344</NumCode>
  61:     <CharCode>HKD</CharCode>
  62:     <Nominal>10</Nominal>
  63:     <Name>Гонконгских долларов</Name>
  64:     <Value>74,9648</Value>
  65: </Valute>
  66: <Valute ID="R01215">
  67:     <NumCode>208</NumCode>
  68:     <CharCode>DKK</CharCode>
  69:     <Nominal>10</Nominal>
  70:     <Name>Датских крон</Name>
  71:     <Value>93,2302</Value>
  72: </Valute>
  73: <Valute ID="R01235">
  74:     <NumCode>840</NumCode>
  75:     <CharCode>USD</CharCode>
  76:     <Nominal>1</Nominal>
  77:     <Name>Доллар США</Name>
  78:     <Value>58,5318</Value>
  79: </Valute>
  80: <Valute ID="R01239">
  81:     <NumCode>978</NumCode>
  82:     <CharCode>EUR</CharCode>
  83:     <Nominal>1</Nominal>
  84:     <Name>Евро</Name>
  85:     <Value>69,3309</Value>
  86: </Valute>
  87: <Valute ID="R01270">
  88:     <NumCode>356</NumCode>
  89:     <CharCode>INR</CharCode>
  90:     <Nominal>100</Nominal>
  91:     <Name>Индийских рупий</Name>
  92:     <Value>90,5539</Value>
  93: </Valute>
  94: <Valute ID="R01335">
  95:     <NumCode>398</NumCode>
  96:     <CharCode>KZT</CharCode>
  97:     <Nominal>100</Nominal>
  98:     <Name>Казахстанских тенге</Name>
  99:     <Value>17,7114</Value>
 100: </Valute>
 101: <Valute ID="R01350">
 102:     <NumCode>124</NumCode>
 103:     <CharCode>CAD</CharCode>
 104:     <Nominal>1</Nominal>
 105:     <Name>Канадский доллар</Name>
 106:     <Value>45,9975</Value>
 107: </Valute>
 108: <Valute ID="R01370">
 109:     <NumCode>417</NumCode>
 110:     <CharCode>KGS</CharCode>
 111:     <Nominal>100</Nominal>
 112:     <Name>Киргизских сомов</Name>
 113:     <Value>83,9194</Value>
 114: </Valute>
 115: <Valute ID="R01375">
 116:     <NumCode>156</NumCode>
 117:     <CharCode>CNY</CharCode>
 118:     <Nominal>10</Nominal>
 119:     <Name>Китайских юаней</Name>
 120:     <Value>88,6349</Value>
 121: </Valute>
 122: <Valute ID="R01500">
 123:     <NumCode>498</NumCode>
 124:     <CharCode>MDL</CharCode>
 125:     <Nominal>10</Nominal>
 126:     <Name>Молдавских леев</Name>
 127:     <Value>33,7359</Value>
 128: </Valute>
 129: <Valute ID="R01535">
 130:     <NumCode>578</NumCode>
 131:     <CharCode>NOK</CharCode>
 132:     <Nominal>10</Nominal>
 133:     <Name>Норвежских крон</Name>
 134:     <Value>71,9099</Value>
 135: </Valute>
 136: <Valute ID="R01565">
 137:     <NumCode>985</NumCode>
 138:     <CharCode>PLN</CharCode>
 139:     <Nominal>1</Nominal>
 140:     <Name>Польский злотый</Name>
 141:     <Value>16,4902</Value>
 142: </Valute>
 143: <Valute ID="R01585F">
 144:     <NumCode>946</NumCode>
 145:     <CharCode>RON</CharCode>
 146:     <Nominal>1</Nominal>
 147:     <Name>Румынский лей</Name>
 148:     <Value>14,9107</Value>
 149: </Valute>
 150: <Valute ID="R01589">
 151:     <NumCode>960</NumCode>
 152:     <CharCode>XDR</CharCode>
 153:     <Nominal>1</Nominal>
 154:     <Name>СДР (специальные права заимствования)</Name>
 155:     <Value>82,5796</Value>
 156: </Valute>
 157: <Valute ID="R01625">
 158:     <NumCode>702</NumCode>
 159:     <CharCode>SGD</CharCode>
 160:     <Nominal>1</Nominal>
 161:     <Name>Сингапурский доллар</Name>
 162:     <Value>43,4502</Value>
 163: </Valute>
 164: <Valute ID="R01670">
 165:     <NumCode>972</NumCode>
 166:     <CharCode>TJS</CharCode>
 167:     <Nominal>10</Nominal>
 168:     <Name>Таджикских сомони</Name>
 169:     <Value>66,3656</Value>
 170: </Valute>
 171: <Valute ID="R01700J">
 172:     <NumCode>949</NumCode>
 173:     <CharCode>TRY</CharCode>
 174:     <Nominal>1</Nominal>
 175:     <Name>Турецкая лира</Name>
 176:     <Value>14,8728</Value>
 177: </Valute>
 178: <Valute ID="R01710A">
 179:     <NumCode>934</NumCode>
 180:     <CharCode>TMT</CharCode>
 181:     <Nominal>1</Nominal>
 182:     <Name>Новый туркменский манат</Name>
 183:     <Value>16,7243</Value>
 184: </Valute>
 185: <Valute ID="R01717">
 186:     <NumCode>860</NumCode>
 187:     <CharCode>UZS</CharCode>
 188:     <Nominal>10000</Nominal>
 189:     <Name>Узбекских сумов</Name>
 190:     <Value>72,3946</Value>
 191: </Valute>
 192: <Valute ID="R01720">
 193:     <NumCode>980</NumCode>
 194:     <CharCode>UAH</CharCode>
 195:     <Nominal>10</Nominal>
 196:     <Name>Украинских гривен</Name>
 197:     <Value>21,7429</Value>
 198: </Valute>
 199: <Valute ID="R01760">
 200:     <NumCode>203</NumCode>
 201:     <CharCode>CZK</CharCode>
 202:     <Nominal>10</Nominal>
 203:     <Name>Чешских крон</Name>
 204:     <Value>27,2844</Value>
 205: </Valute>
 206: <Valute ID="R01770">
 207:     <NumCode>752</NumCode>
 208:     <CharCode>SEK</CharCode>
 209:     <Nominal>10</Nominal>
 210:     <Name>Шведских крон</Name>
 211:     <Value>70,4829</Value>
 212: </Valute>
 213: <Valute ID="R01775">
 214:     <NumCode>756</NumCode>
 215:     <CharCode>CHF</CharCode>
 216:     <Nominal>1</Nominal>
 217:     <Name>Швейцарский франк</Name>
 218:     <Value>59,6350</Value>
 219: </Valute>
 220: <Valute ID="R01810">
 221:     <NumCode>710</NumCode>
 222:     <CharCode>ZAR</CharCode>
 223:     <Nominal>10</Nominal>
 224:     <Name>Южноафриканских рэндов</Name>
 225:     <Value>41,9715</Value>
 226: </Valute>
 227: <Valute ID="R01815">
 228:     <NumCode>410</NumCode>
 229:     <CharCode>KRW</CharCode>
 230:     <Nominal>1000</Nominal>
 231:     <Name>Вон Республики Корея</Name>
 232:     <Value>53,9061</Value>
 233: </Valute>
 234: <Valute ID="R01820">
 235:     <NumCode>392</NumCode>
 236:     <CharCode>JPY</CharCode>
 237:     <Nominal>100</Nominal>
 238:     <Name>Японских иен</Name>
 239:     <Value>52,5538</Value>
 240: </Valute>
 241: </ValCurs>

It shows conversion ratios related with Russian Ruble, e.g. if we check EUR:

   1: <Valute ID="R01239">
   2:     <NumCode>978</NumCode>
   3:     <CharCode>EUR</CharCode>
   4:     <Nominal>1</Nominal>
   5:     <Name>Евро</Name>
   6:     <Value>69,3309</Value>
   7: </Valute>

it shows that 1 (Nominal) Euro is equal to 69,3309 (Value) Rub. Having conversion ratios for all currencies and Ruble it is possible to get conversion ratios between any 2 currencies using simple proportions math. The following code shows how to convert value between RUR, EUR and USD in any order and direction:

   1:  
   2: public decimal? Convert(decimal sourceValue, Currency sourceCurrency, Currency targetCurrency)
   3: {
   4:     try
   5:     {
   6:         if (sourceCurrency == targetCurrency)
   7:         {
   8:             return sourceValue;
   9:         }
  10:  
  11:         var now = DateTime.Now;
  12:         string url = string.Format("http://www.cbr.ru/scripts/XML_daily.asp?date_req={0}",
  13:             now.ToString("dd/MM/yyyy"));
  14:         string str = this.webClient.Download(url, Encoding.GetEncoding("windows-1251"));
  15:         if (string.IsNullOrEmpty(str))
  16:         {
  17:             return null;
  18:         }
  19:         var doc = XDocument.Parse(str);
  20:         var elEUR = doc.Root.Elements("Valute").FirstOrDefault(e =>
  21:             e.Elements("CharCode").ElementAt(0).Value == "EUR");
  22:         decimal? nominalEUR =
  23:             DecimalHelper.ParseWithDotSeparator(elEUR.Element("Nominal").Value);
  24:         decimal? valueEUR =
  25:             DecimalHelper.ParseWithDotSeparator(elEUR.Element("Value").Value);
  26:  
  27:         var elUSD = doc.Root.Elements("Valute").FirstOrDefault(e =>
  28:             e.Elements("CharCode").ElementAt(0).Value == "USD");
  29:         decimal? nominalUSD =
  30:             DecimalHelper.ParseWithDotSeparator(elUSD.Element("Nominal").Value);
  31:         decimal? valueUSD =
  32:             DecimalHelper.ParseWithDotSeparator(elUSD.Element("Value").Value);
  33:  
  34:         double koefFromEURtoRUB = (double)valueEUR.Value / (double)nominalEUR.Value;
  35:         double koefFromUSDtoRUB = (double)valueUSD.Value / (double)nominalUSD.Value;
  36:  
  37:         double koefFromRUBtoEUR = 1 / koefFromEURtoRUB;
  38:         double koefFromUSDtoEUR = koefFromUSDtoRUB / koefFromEURtoRUB;
  39:  
  40:         double koefFromRUBtoUSD = 1 / koefFromUSDtoRUB;
  41:         double koefFromEURtoUSD = koefFromEURtoRUB / koefFromUSDtoRUB;
  42:  
  43:         double? koeff = null;
  44:         if (sourceCurrency == Currency.Rub)
  45:         {
  46:             if (targetCurrency == Currency.Eur)
  47:             {
  48:                 koeff = koefFromRUBtoEUR;
  49:             }
  50:             else if (targetCurrency == Currency.Usd)
  51:             {
  52:                 koeff = koefFromRUBtoUSD;
  53:             }
  54:         }
  55:         else if (sourceCurrency == Currency.Eur)
  56:         {
  57:             if (targetCurrency == Currency.Rub)
  58:             {
  59:                 koeff = koefFromEURtoRUB;
  60:             }
  61:             else if (targetCurrency == Currency.Usd)
  62:             {
  63:                 koeff = koefFromEURtoUSD;
  64:             }
  65:         }
  66:         else if (sourceCurrency == Currency.Usd)
  67:         {
  68:             if (targetCurrency == Currency.Rub)
  69:             {
  70:                 koeff = koefFromUSDtoRUB;
  71:             }
  72:             else if (targetCurrency == Currency.Eur)
  73:             {
  74:                 koeff = koefFromUSDtoEUR;
  75:             }
  76:         }
  77:         if (koeff == null)
  78:         {
  79:             return null;
  80:         }
  81:  
  82:         var targetValue = (decimal)Math.Round(((double)sourceValue) * koeff.Value, 2);
  83:         return targetValue;
  84:     }
  85:     catch (Exception x)
  86:     {
  87:         return null;
  88:     }
  89: }

Helper classes WebClient and DecimalHelper look like this:

   1: public class WebClient
   2: {
   3:     public string Download(string url, Encoding encoding)
   4:     {
   5:         try
   6:         {
   7:             if (string.IsNullOrEmpty(url))
   8:             {
   9:                 return string.Empty;
  10:             }
  11:             byte[] data;
  12:             using (var webClient = new System.Net.WebClient())
  13:             {
  14:                 data = webClient.DownloadData(url);
  15:             }
  16:             if (data == null)
  17:             {
  18:                 return string.Empty;
  19:             }
  20:             return encoding.GetString(data);
  21:         }
  22:         catch (Exception x)
  23:         {
  24:             return string.Empty;
  25:         }
  26:     }
  27: }

and

   1: public class DecimalHelper
   2: {
   3:     public static decimal? ParseWithDotSeparator(string val)
   4:     {
   5:         if (string.IsNullOrEmpty(val))
   6:         {
   7:             return null;
   8:         }
   9:         return decimal.Parse(val.Replace(",", "."), CultureInfo.InvariantCulture);
  10:     }
  11: }

Convert method receives 3 parameters:

  1. source value
  2. source currency
  3. target currency

At first we download current ratios from web service (lines 10-17). Then we calculate ratios for all required conversions EUR to RUR, USD to RUR, RUR to EUR, USD to EUR, RUR to USD, EUR to USD (lines 35-42) and choice correct ratio depending on arguments. If you will compare result with one get from Google (try to google e.g. eur to usd – Google will show conversion calculator), you will see that it is almost the same. Of course if conversion accuracy is crucial for your app then you need to use another web service which is updated more frequently.