4

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.

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:

<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?

shytikov
  • 9,155
  • 8
  • 56
  • 103

3 Answers3

1

Yes, you can perform all of your web service, or client, configuration in code using either VB or C#. 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
{
}
Brian
  • 3,653
  • 1
  • 22
  • 33
  • What I've given you there is just a guide ... you'll have to sub in your own values. I don't think you can use "http: //server/XRMDeployment/2011/Deployment.svc" as your endpoint address in the way I've described it. You'd need a real URL. And the values you have defined in your "CustomBinding_IDeploymentService" would need to be added in the appropriate places in the code sample I've provided. – Brian Feb 25 '14 at 15:05
  • That's I'm trying to do, but unfortunately there is no place for `contract` in my config for example. `EndpointIdentity` is not used in your code at all. `default(System.ServiceModel.EndpointIdentity)` returns null. `default(System.ServiceModel.BasicHttpBinding)` returns null as well... – shytikov Feb 25 '14 at 15:09
  • Contract wise, check out the edit I made in my answer. On the client side, when configuring your client in code, the contract is configure at just above the interface class you're using. I don't use the endpoint identity in my code so I'm not sure where you'd set that. – Brian Feb 25 '14 at 15:24
  • Any luck with the solution? – Brian Feb 26 '14 at 08:09
  • Actually yes, I've accepted one answer already. It works. You can check. – shytikov Mar 03 '14 at 08:54
1

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")

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.

in the catch you can do some error handling or retrial but on my case its not used.

Marc
  • 12,706
  • 7
  • 61
  • 97
Pedro.The.Kid
  • 1,968
  • 1
  • 14
  • 18
1

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

Community
  • 1
  • 1
G_Iashyn
  • 178
  • 5