简体   繁体   English

使用WCF服务的代码配置替换app.config中的配置

[英]Replace configuration in app.config with code configuration for WCF service

I'm trying to connect to DevelpmentService of MS CRM from custom plugin and thus I'm not able to use app.config generated when I added WebReference to solution. 我试图连接到DevelpmentService从自定义插件MS CRM的,因此我不能够使用app.config当我添加Web引用到溶液中生成。

Here is the working code: 这是工作代码:

var id = new EntityInstanceId
{
    Id = new Guid("682f3258-48ff-e211-857a-2c27d745b005")
};

var client = new DeploymentServiceClient("CustomBinding_IDeploymentService");

var organization = (Organization)client.Retrieve(DeploymentEntityType.Organization, id);

And corresponding part of the app.config : app.config相应部分:

<client>
    <endpoint address="http://server/XRMDeployment/2011/Deployment.svc"
        binding="customBinding" bindingConfiguration="CustomBinding_IDeploymentService"
        contract="DeploymentService.IDeploymentService" name="CustomBinding_IDeploymentService">
        <identity>
            <userPrincipalName value="DOMAIN\DYNAMICS_CRM" />
        </identity>
    </endpoint>

    ...

</client>

Is it possible to transform code in the way when configuration file will not be needed. 是否可以在不需要配置文件时转换代码。 How? 怎么样?

Yes, you can perform all of your web service, or client, configuration in code using either VB or C#. 是的,您可以使用VB或C#在代码中执行所有Web服务或客户端配置。 In some ways, really, it's better to configure in code since your code can be written to configure dynamically based on variables or existing conditions. 在某些方面,实际上,最好在代码中进行配置,因为您的代码可以根据变量或现有条件动态配置。

Basically, you can do something like this: 基本上,你可以做这样的事情:

//end point setup
System.ServiceModel.EndpointAddress EndPoint = new System.ServiceModel.EndpointAddress("http://Domain:port/Class/Method");
System.ServiceModel.EndpointIdentity EndpointIdentity = default(System.ServiceModel.EndpointIdentity);

//binding setup
System.ServiceModel.BasicHttpBinding binding = default(System.ServiceModel.BasicHttpBinding);

binding.TransferMode = TransferMode.Streamed;
//add settings
binding.MaxReceivedMessageSize = int.MaxValue;
binding.ReaderQuotas.MaxArrayLength = int.MaxValue;
binding.ReaderQuotas.MaxBytesPerRead = int.MaxValue;
binding.ReaderQuotas.MaxDepth = int.MaxValue;
binding.ReaderQuotas.MaxNameTableCharCount = int.MaxValue;
binding.MaxReceivedMessageSize = int.MaxValue;
binding.ReaderQuotas.MaxStringContentLength = int.MaxValue;

binding.MessageEncoding = WSMessageEncoding.Text;
binding.TextEncoding = System.Text.Encoding.UTF8;
binding.MaxBufferSize = int.MaxValue;
binding.MaxBufferPoolSize = int.MaxValue;
binding.MaxReceivedMessageSize = int.MaxValue;
binding.SendTimeout = new TimeSpan(0, 10, 0);
binding.ReceiveTimeout = new TimeSpan(0, 10, 0);

//setup for custom binding
System.ServiceModel.Channels.CustomBinding CustomBinding = new System.ServiceModel.Channels.CustomBinding(binding);

What I do to configure my contract: 我做什么来配置我的合同:

[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0"), System.ServiceModel.ServiceContractAttribute(Namespace = "http://MyNameSpace", ConfigurationName = "IHostInterface")]
public interface IHostInterface
{
}

this is working on my live environment 这是在我的生活环境

public static TResult UseService<TChannel, TResult>(string url,
                                                    EndpointIdentity identity,
                                                    NetworkCredential credential,
                                                    Func<TChannel, TResult> acc)
{
    var binding = new BasicHttpBinding();
    binding.Security.Mode = BasicHttpSecurityMode.TransportCredentialOnly;
    binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Windows;
    var endPointAddress = new EndpointAddress(new Uri(url), identity,
                                              new AddressHeaderCollection());
    var factory = new ChannelFactory<T>(binding, address);
    var loginCredentials = new ClientCredentials();
    loginCredentials.Windows.ClientCredential = credentials;

    foreach (var cred in factory.Endpoint.EndpointBehaviors.Where(b => b is ClientCredentials).ToArray())
        factory.Endpoint.EndpointBehaviors.Remove(cred);

    factory.Endpoint.EndpointBehaviors.Add(loginCredentials);
    TChannel channel = factory.CreateChannel();
    bool error = true;
    try
    {
        TResult result = acc(channel);
        ((IClientChannel)channel).Close();
        error = false;
        factory.Close();
        return result;
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.ToString());
        return default(TResult);
    }
    finally
    {
        if (error)
            ((IClientChannel)channel).Abort();
    }
}

where Identity = new SpnEndpointIdentity("") and Credentials = new NetworkCredential("User", "Pass", "server") 其中Identity = new SpnEndpointIdentity("")Credentials = new NetworkCredential("User", "Pass", "server")

usage 用法

NameSpace.UseService("http://server/XRMDeployment/2011/Deployment.svc",
                     Identity,
                     Credentials,
(IOrganizationService context) =>
{ 
   ... your code here ...
   return true;
});

this supposes windows Authentication and SpnEndpointIdentity witch have a very long base64 string I'm not sure if you have this case. 这假设windows身份验证和SpnEndpointIdentity有一个非常长的base64字符串我不确定你是否有这种情况。

in the catch you can do some error handling or retrial but on my case its not used. 在捕获中你可以做一些错误处理或重审,但在我的情况下它没有使用。

It should work 它应该工作

 var id = new EntityInstanceId
 {
     Id = new Guid("682f3258-48ff-e211-857a-2c27d745b005")
 };

 var endpoint = new EndpointAddress(new Uri("http://server/XRMDeployment/2011/Deployment.svc"),
                    EndpointIdentity.CreateUpnIdentity(@"DOMAIN\DYNAMICS_CRM"));

 var login = new ClientCredentials();
 login.Windows.ClientCredential = CredentialCache.DefaultNetworkCredentials;

 var binding = new CustomBinding();

 //Here you may config your binding (example in the link at the bottom of the post)

 var client = new DeploymentServiceClient(binding, endpoint);

 foreach (var credential in client.Endpoint.Behaviors.Where(b => b is ClientCredentials).ToArray())
 {
     client.Endpoint.Behaviors.Remove(credential);
 }

 client.Endpoint.Behaviors.Add(login);
 var organization = (Organization)client.Retrieve(DeploymentEntityType.Organization, id);

Here you may find the example of using code instead of config file 在这里,您可以找到使用代码而不是配置文件的示例

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM