Как установить правильный тип содержимого в привязке WCF без использования app.config? - PullRequest
2 голосов
/ 23 сентября 2011

Я создал сервисную ссылку на CRM 2011 Organization.svc из тестового консольного приложения. Все отлично работает с использованием привязки, сгенерированной в app.config. (Пример службы, размещенной в Microsoft здесь .)

Теперь это нужно перенести в наше «реальное» приложение и разместить в DLL, которая будет развернута в GAC. В соответствии с соглашениями приложения, привязка должна генерироваться кодом .

Я начал пытаться использовать привязку, которую мы используем для других наших служб WCF:

BasicHttpBinding binding = new BasicHttpBinding();
binding.SendTimeout = TimeSpan.FromMinutes(1);
binding.OpenTimeout = TimeSpan.FromMinutes(1);
binding.CloseTimeout = TimeSpan.FromMinutes(1);
binding.ReceiveTimeout = TimeSpan.FromMinutes(10);
binding.AllowCookies = true;
binding.BypassProxyOnLocal = false;
binding.HostNameComparisonMode = HostNameComparisonMode.StrongWildcard;
binding.MessageEncoding = WSMessageEncoding.Text;
binding.TextEncoding = System.Text.Encoding.UTF8;
binding.TransferMode = TransferMode.Buffered;
binding.UseDefaultWebProxy = true;
binding.Security.Mode = BasicHttpSecurityMode.TransportCredentialOnly;
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Windows;

К сожалению, в момент вызова службы WCF (с использованием метода Execute с OrganizationRequest) возникает эта ошибка:

System.ServiceModel.ProtocolException: Тип содержимого text / xml; charset = utf-8 не поддерживается службой http://server:5555/xrmservices/2011/organization.svc. Привязки клиента и службы могут не совпадать.

Я не уверен, , в чем конкретно заключается проблема с привязкой , но мои попытки преобразовать ее в код потерпели неудачу с той же ошибкой. Вот рабочая привязка, определенная в app.config:

<bindings>
    <customBinding>
        <binding name="CustomBinding_IOrganizationService">
            <security defaultAlgorithmSuite="Default" authenticationMode="SspiNegotiated"
                requireDerivedKeys="true" securityHeaderLayout="Strict" includeTimestamp="true"
                keyEntropyMode="CombinedEntropy" messageProtectionOrder="SignBeforeEncryptAndEncryptSignature"
                messageSecurityVersion="WSSecurity11WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10"
                requireSecurityContextCancellation="true" requireSignatureConfirmation="false">
                <localClientSettings cacheCookies="true" detectReplays="true"
                    replayCacheSize="900000" maxClockSkew="00:05:00" maxCookieCachingTime="Infinite"
                    replayWindow="00:05:00" sessionKeyRenewalInterval="10:00:00"
                    sessionKeyRolloverInterval="00:05:00" reconnectTransportOnFailure="true"
                    timestampValidityDuration="00:05:00" cookieRenewalThresholdPercentage="60" />
                <localServiceSettings detectReplays="true" issuedCookieLifetime="10:00:00"
                    maxStatefulNegotiations="128" replayCacheSize="900000" maxClockSkew="00:05:00"
                    negotiationTimeout="00:01:00" replayWindow="00:05:00" inactivityTimeout="00:02:00"
                    sessionKeyRenewalInterval="15:00:00" sessionKeyRolloverInterval="00:05:00"
                    reconnectTransportOnFailure="true" maxPendingSessions="128"
                    maxCachedCookies="1000" timestampValidityDuration="00:05:00" />
                <secureConversationBootstrap />
            </security>
            <textMessageEncoding maxReadPoolSize="64" maxWritePoolSize="16"
                messageVersion="Default" writeEncoding="utf-8">
                <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
                    maxBytesPerRead="4096" maxNameTableCharCount="16384" />
            </textMessageEncoding>
            <httpTransport manualAddressing="false" maxBufferPoolSize="524288"
                maxReceivedMessageSize="65536" allowCookies="false" authenticationScheme="Anonymous"
                bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
                keepAliveEnabled="true" maxBufferSize="65536" proxyAuthenticationScheme="Anonymous"
                realm="" transferMode="Buffered" unsafeConnectionNtlmAuthentication="false"
                useDefaultWebProxy="true" />
        </binding>
    </customBinding>
</bindings>

Кто-нибудь знает, как установить правильную привязку в коде и / или прочитать привязку из XML?

Ответы [ 2 ]

2 голосов
/ 12 января 2012

Мне просто нужно было решить ту же задачу.Это сработало для меня (для http).

var security = SecurityBindingElement.CreateSspiNegotiationBindingElement();
security.DefaultAlgorithmSuite = SecurityAlgorithmSuite.Default;
security.SecurityHeaderLayout = SecurityHeaderLayout.Strict;
security.IncludeTimestamp = true;
security.KeyEntropyMode = SecurityKeyEntropyMode.CombinedEntropy;
security.MessageProtectionOrder = MessageProtectionOrder.SignBeforeEncryptAndEncryptSignature;
security.MessageSecurityVersion = MessageSecurityVersion.WSSecurity11WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10;

security.LocalClientSettings.CacheCookies = true;
security.LocalClientSettings.DetectReplays = true;
security.LocalClientSettings.ReplayCacheSize = 900000;
security.LocalClientSettings.MaxClockSkew = new TimeSpan(0, 5, 0);
security.LocalClientSettings.MaxCookieCachingTime = new TimeSpan(23, 0, 0, 0);
security.LocalClientSettings.ReplayWindow = new TimeSpan(0, 5, 0);
security.LocalClientSettings.SessionKeyRenewalInterval = new TimeSpan(15, 0, 0);
security.LocalClientSettings.SessionKeyRolloverInterval = new TimeSpan(0, 5, 0);
security.LocalClientSettings.ReconnectTransportOnFailure = true;
security.LocalClientSettings.TimestampValidityDuration = new TimeSpan(0, 5, 0);
security.LocalClientSettings.CookieRenewalThresholdPercentage = 60;

security.LocalServiceSettings.DetectReplays = true;
security.LocalServiceSettings.IssuedCookieLifetime = new TimeSpan(10, 0, 0);
security.LocalServiceSettings.MaxStatefulNegotiations = 128;
security.LocalServiceSettings.ReplayCacheSize = 900000;
security.LocalServiceSettings.MaxClockSkew = new TimeSpan(0, 5, 0);
security.LocalServiceSettings.NegotiationTimeout = new TimeSpan(0, 1, 0);
security.LocalServiceSettings.ReplayWindow = new TimeSpan(0, 5, 0);
security.LocalServiceSettings.InactivityTimeout = new TimeSpan(0, 2, 0);
security.LocalServiceSettings.SessionKeyRenewalInterval = new TimeSpan(15, 0, 0);
security.LocalServiceSettings.SessionKeyRolloverInterval = new TimeSpan(0, 5, 0);
security.LocalServiceSettings.ReconnectTransportOnFailure = true;
security.LocalServiceSettings.MaxPendingSessions = 128;
security.LocalServiceSettings.MaxCachedCookies = 1000;
security.LocalServiceSettings.TimestampValidityDuration = new TimeSpan(0, 5, 0);

var textEncoding = new TextMessageEncodingBindingElement
{
   MaxReadPoolSize = 64,
   MaxWritePoolSize = 16,
   MessageVersion = MessageVersion.Default,
   WriteEncoding = System.Text.Encoding.UTF8,
   ReaderQuotas = new XmlDictionaryReaderQuotas
   {
       MaxDepth = 32,
       MaxArrayLength = 16384,
       MaxBytesPerRead = 4096,
       MaxNameTableCharCount = 16384,
       MaxStringContentLength = 8192
   }
};

var httpTransport = new HttpTransportBindingElement
{
    ManualAddressing = false,
    MaxBufferSize = 65536,
    MaxReceivedMessageSize = 65536,
    AllowCookies = false,
    AuthenticationScheme = AuthenticationSchemes.Anonymous,
    BypassProxyOnLocal = false,
    DecompressionEnabled = true,
    HostNameComparisonMode = HostNameComparisonMode.StrongWildcard,
    KeepAliveEnabled = true,
    MaxBufferPoolSize = 524288,
    ProxyAuthenticationScheme = AuthenticationSchemes.Anonymous,
    TransferMode = TransferMode.Buffered,
    UnsafeConnectionNtlmAuthentication = false,
    UseDefaultWebProxy = true,
};

var binding = new CustomBinding(new List<BindingElement> { security, textEncoding, httpTransport });
var endpoint = new EndpointAddress(_serviceUri);

var service = new OrganizationServiceClient(binding, endpoint);
1 голос
/ 23 сентября 2011

Создание фабрики пользовательских каналов является ключевой частью решения этой проблемы.

Статья Получение конфигурации клиента WCF из любого места очень полезно для чтения a.Конфигурационный файл из выбранного вами местоположения с помощью пользовательского сервисного клиента.

Альтернатива установки всех значений очень похожим на формат app.config описана в Вызов службы WCF с использованием клиентского каналаФабрика , которая описывает, как создать пользовательскую привязку.Я обнаружил, что не все свойства безопасности могут быть установлены таким образом (или, по крайней мере, я не смог их найти).

...