Le Windows Communication Foundation permettono una configurazione molto semplice e efficace, risolvendo in automatico i binding e tutte le configurazioni di channel, porte e quanto altro direttamente leggendo da web.config oppure da un app.config.
Il problema nasce quando andiamo a utilizzare ad esempio un client verso un servizio wcf , direttamente in delle application pages o webpart all’interno di Sharepoint.
In questo caso la configurazione può essere gestita in 3 modi:
Nel primo caso dobbiamo mettere mano al web.config di Sharepoint, in quanto le application pages e/o le webpart sono hostate all’interno della sua Web Applicaiton, e questo per motivi di policy, non sempre è possibile.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | <system.serviceModel> <bindings> <basicHttpBinding> <binding name="RichiestaDatiSoapBinding" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard" maxBufferSize="2147483647" maxBufferPoolSize="524288" maxReceivedMessageSize="2147483647" messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered" useDefaultWebProxy="true"> <readerQuotas maxDepth="32" maxStringContentLength="2147483647" maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384" /> <security mode="None"> <transport clientCredentialType="None" proxyCredentialType="None" realm="" /> <message clientCredentialType="UserName" algorithmSuite="Default" /> </security> </binding> </basicHttpBinding> </bindings> <client> <endpoint address="http://localhost:81/testservice/servizio.asmx" binding="basicHttpBinding" bindingConfiguration="RichiestaDatiSoapBinding" contract="TestService.RichiestaDatiSoapBinding" name="RichiestaDatiSoapBinding" /> </client> </system.serviceModel> |
Il secondo meccanismo , messo a disposizione direttamente dalle Api di Sharepoint, prevede l’utilizzo delle SPWebConfigModification Api, che permettonod i manipolare il web.config di iis, mediante codice, andando ad aggiungere le parti che servono in fase , ad esempio, di attivazione di una feature.. A mio avviso questa parte è qualcosa di veramente terrificante, perche si arriva ad ottenere un web.config spesso illeggibile e quasi sempre non funzionante e oltretutto difficile da controllare visto che tutto il value che deve essere passato al configModification deve avere l’escape di tutti i caratteri particolari.. quindi pieno di entity xml come il @quot …
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | SPWebConfigModification modificaWebConfig= new SPWebConfigModification(); modificaWebConfig.Path = "configuration/system.serviceModel"; modificaWebConfig.Sequence = 0; modificaWebConfig.Type = SPWebConfigModification.SPWebConfigModificationType.EnsureChildNode; modificaWebConfig.Owner = System.Threading.Thread.CurrentPrincipal.Identity.Name; modificaWebConfig.Value = @"<bindings><basicHttpBinding>..etc.etc..inserire qui tutto l'xml del binding"; SPWebService service = SPWebService.ContentService; service.WebConfigModifications.Add(modificaWebConfig); service.Update(); service.ApplyWebConfigModifications(); |
Un terzo modo è quello di creare una classe che fornisca direttamente il Binding (BasicHttpBinding) e l’Endpoint (EndPointAddess).
Purtroppo per motivi di sicurezza , microsoft ha bloccato la possibilità di leggere l’xml e deserializzarlo nelle relative classi messe a disposizioni dal Framework, quindi la creazione del binding va fatta “a mano”.
I dati possono essere statiticizzati nel codice o ad esempio letti da una Lista di Sharepoint, in cui magari andiamo a memorizzare in un unico Item tutto il blocco xml della configurazione del binding .
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | public class WCFClientConfiguration { public BasicHttpBinding Binding { get { BasicHttpBinding _binding = new BasicHttpBinding() { Name = "ServizioTestSoap", CloseTimeout = new TimeSpan(1, 5, 0), OpenTimeout = new TimeSpan(1, 5, 0), ReceiveTimeout = new TimeSpan(1, 10, 0), SendTimeout = new TimeSpan(1, 5, 0), AllowCookies = false, BypassProxyOnLocal = true, HostNameComparisonMode = HostNameComparisonMode.StrongWildcard, MaxBufferSize = 600000, MaxBufferPoolSize = 524288, MaxReceivedMessageSize = 600000, MessageEncoding = WSMessageEncoding.Text, TextEncoding = System.Text.Encoding.UTF8, TransferMode = TransferMode.Buffered, UseDefaultWebProxy = false, ReaderQuotas = new XmlDictionaryReaderQuotas() { MaxDepth = 32, MaxStringContentLength = 500000, MaxArrayLength = 16384, MaxBytesPerRead = 4096, MaxNameTableCharCount = 16384 } }; _binding.Security.Mode = BasicHttpSecurityMode.Transport; return _binding; } } public EndpointAddress Endpoint { get { return new EndpointAddress("https://localhost:81/testService/service.asmx"); } } } |
In questo modo quando andiamo a instanziare il nostro client, usiamo il costruttore che accetta in input Binding e Endpoint.
1 2 3 | WcfConfiguration conf = new WCFClientConfiguration(); ServizioTestSoapClient client = new ServizioTestSoapClient (conf.Binding,conf.Endpoint); |
Questo permette la memorizzazione ad esempio della configurazione su DB o su altri sistemi di persistenza .