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 .