Binding in the client + WCF - c#

I use visual studio 11 to add service (Add service Reference).
When I added the service Article, I have An articleClient with one constructor:
public RssArticleServiceClient(System.ServiceModel.Channels.Binding binding, System.ServiceModel.EndpointAddress remoteAddress) :
base(binding, remoteAddress) {
}
How can I use this constructor, i don't know which value of binding should I use??
Any example or sample please??
Merci
Best regards
I do this:
BasicHttpSecurityMode securitymode = BasicHttpSecurityMode.Transport; BasicHttpBinding binding = new BasicHttpBinding(securitymode); binding.MaxReceivedMessageSize = int.MaxValue; binding.MaxBufferSize = int.MaxValue; Uri uri = new Uri("adresse/RssArticleService.svc";); _clientArticles = new RssArticleServiceClient(binding, new EndpointAddress("adresse/RssArticleService.svc";)); var result=await _clientArticles.GetRssDataAsync("1", "fr");
And A cath this error:
**here was no endpoint listening at adresse/RssArticleService.svc that could accept the message. This is often caused by an incorrect address or SOAP**
What can i do, should i change the type of binding??

This is my implementation :
BasicHttpSecurityMode securitymode = HostSource.Scheme.Equals("https", StringComparison.InvariantCultureIgnoreCase) ? BasicHttpSecurityMode.Transport : BasicHttpSecurityMode.None;
BasicHttpBinding binding = new BasicHttpBinding(securitymode);
binding.MaxReceivedMessageSize = int.MaxValue;
binding.MaxBufferSize = int.MaxValue;
Uri uri = new Uri(Application.Current.Host.Source, "../service.svc");
_client = new RssArticleServiceClient(binding, new EndpointAddress(uri))
EDIT : you need to add this in your web.config :
<system.serviceModel>
<services>
<service name="namespace.RssArticleService"
behaviorConfiguration="RssArticleServiceBehavior">
<endpoint address=""
binding="basicHttpBinding"
contract="namespace.IRssArticleService"/>
</service>
</services>
<serviceBehaviors>
<behavior name="RssArticleServiceBehavior">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true"/>
</system.serviceModel>

Related

Calling duplex wcf service method from uwp have no effect

I am developing an UWP application which consumes wcf duplex service made by myself. The problem occurs when I try to call a method from service, literally method does not firing up and no breakpoint in service code is hitted.
This is my configuration in host application
<system.serviceModel>
<services>
<service name="WcfService.Services.ImageExchangeService" behaviorConfiguration="behaviorConfig">
<endpoint address="net.tcp://localhost:4322/WcfService/Services/ImageExchangeService/tcp" binding="netTcpBinding" contract="WcfService.Services.IImageExchangeService" bindingConfiguration="tcpBinding"></endpoint>
<endpoint address="net.tcp://localhost:4323/WcfService/Services/ImageExchangeService/mex" binding="mexTcpBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:4321/WcfService/Services/ImageExchangeService" />
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="behaviorConfig">
<!-- To avoid disclosing metadata information,
set the values below to false before deployment -->
<serviceMetadata httpGetEnabled="True" httpsGetEnabled="True"/>
<!-- To receive exception details in faults for debugging purposes,
set the value below to true. Set to false before deployment
to avoid disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="False" />
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<netTcpBinding>
<binding name="tcpBinding">
<security mode="None"></security>
<reliableSession enabled="true"/>
</binding>
</netTcpBinding>
</bindings>
</system.serviceModel>
This is my service interface
[ServiceContract(CallbackContract = typeof(IImageExchangeClient), SessionMode =SessionMode.Required)]
public interface IImageExchangeService
{
[OperationContract(IsOneWay = true)]
void Connect(string deviceIdentifier);
}
This is my implementation of above interface
[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Single, IncludeExceptionDetailInFaults =true)]
public class ImageExchangeService : IImageExchangeService
{
private Dictionary<string, IImageExchangeClient> _connectedDevices = new Dictionary<string, IImageExchangeClient>();
public void Connect(string deviceIdentifier)
{
var connection = OperationContext.Current.GetCallbackChannel<IImageExchangeClient>();
if (!_connectedDevices.ContainsKey(deviceIdentifier))
{
_connectedDevices.Add(deviceIdentifier, connection);
}
else
{
_connectedDevices[deviceIdentifier] = connection;
}
Console.WriteLine("\nDevice connected: {0}", deviceIdentifier);
}
}
and finally this is my UWP code where I trying to call Connect method
public async void InitializeImageExchangeClient()
{
var endpoint = new EndpointAddress(new Uri("net.tcp://localhost:4322/WcfService/Services/ImageExchangeService/tcp"));
var InstanceContext = new InstanceContext(new ImageExchangeCallback());
var client = new ImageExchangeService.ImageExchangeServiceClient(buildBinding(), endpoint);
var channelFactory = (DuplexChannelFactory<IImageExchangeService>)(client.ChannelFactory);
var proxy = channelFactory.CreateChannel(InstanceContext);
await proxy.ConnectAsync(DeviceIdentifier);
}
I have also tried other approach of cal this method like:
var client = new ImageExchangeServiceClientBase(InstanceContext, buildBinding(), endpoint);
await client.OpenAsync();
await client.ConnectAsync(DeviceIdentifier);
buildBinding() function looks like this:
private NetTcpBinding buildBinding()
{
var binding = new NetTcpBinding()
{
MaxReceivedMessageSize = int.MaxValue,
MaxBufferPoolSize = int.MaxValue,
ReaderQuotas = new System.Xml.XmlDictionaryReaderQuotas()
{
MaxArrayLength = int.MaxValue,
MaxBytesPerRead = int.MaxValue,
MaxDepth = int.MaxValue,
MaxNameTableCharCount = int.MaxValue,
MaxStringContentLength = int.MaxValue
},
OpenTimeout = TimeSpan.MaxValue,
ReceiveTimeout = TimeSpan.MaxValue,
};
binding.Security.Mode = SecurityMode.None;
binding.Security.Transport.ClientCredentialType = TcpClientCredentialType.None;
binding.Security.Message.ClientCredentialType = MessageCredentialType.None;
return binding;
}
Actual result is the method Connect is not firing up, and when I toggle breakpoint on this method it is not hitted.
Other non-duplex services are working fine without a problem.
When I implemented this service in WPF application the method is calling properly and everything works fine, the problem is when I trying to implement this in UWP architecture.
Thanks for help in advance.

Set the Thread.CurrentPrincipal from IAuthorizationPolicy?

I have a WCF service running under .NET Framework 4.6.2. I have used the web.config before to configure the service with my custom IAuthorizationPolicy like this :
<services>
behaviorConfiguration="MyClientService.CustomValidator_Behavior" name="My.Service.Implementation.Services.MyClientService">
<endpoint binding="netHttpBinding" behaviorConfiguration="protoEndpointBehavior" address="BinaryHttpProto" bindingNamespace="http://My.ServiceContracts/2007/11" contract="My.ServiceContracts.IMyClientService" />
<endpoint binding="netHttpsBinding" behaviorConfiguration="protoEndpointBehavior" address="BinaryHttpsProto" bindingNamespace="http://My.ServiceContracts/2007/11" contract="My.ServiceContracts.IMyClientService" />
bindingConfiguration="netTcpCertificate" behaviorConfiguration="protoEndpointBehavior" bindingNamespace="http://My.ServiceContracts/2007/11" contract="My.ServiceContracts.IMyClientService" address="Sll"/>
<host>
</host>
</service>
</services>
<behavior name="MyClientService.CustomValidator_Behavior">
<dataContractSerializer maxItemsInObjectGraph="2147483647" />
<serviceDebug includeExceptionDetailInFaults="true" />
<serviceMetadata httpGetEnabled="true" />
<customBehaviorExtension_ClientService />
<serviceThrottling maxConcurrentCalls="2000" maxConcurrentSessions="2147483647" maxConcurrentInstances="2000" />
<serviceCredentials>
<clientCertificate>
<authentication certificateValidationMode="PeerOrChainTrust" />
</clientCertificate>
<userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="My.Service.Implementation.Security.CustomUsernamePasswordValidator, My.Service.Implementation" />
</serviceCredentials>
<serviceAuthorization principalPermissionMode="Custom" serviceAuthorizationManagerType="My.Service.Implementation.Security.CustomServiceAuthorizationManager, My.Service.Implementation">
<authorizationPolicies>
<add policyType="My.Service.Implementation.Security.CustomAuthorizationPolicy_ClientService, My.Service.Implementation" />
</authorizationPolicies>
</serviceAuthorization>
</behavior>
Now I need to swtich to do this in code and this is what that looks like :
var endpoint = new System.ServiceModel.Description.ServiceEndpoint(System.ServiceModel.Description.ContractDescription.GetContract(typeof(IMyClientService)),
binding,
new EndpointAddress(endPointAddress));
endpoint.EndpointBehaviors.Add(new ProtoBuf.ServiceModel.ProtoEndpointBehavior());
serviceHost.AddServiceEndpoint(endpoint);
ServiceAuthorizationBehavior serviceAuthorizationBehavior = serviceHost.Description.Behaviors.Find<ServiceAuthorizationBehavior>();
if (serviceAuthorizationBehavior == null)
{
serviceAuthorizationBehavior = new ServiceAuthorizationBehavior();
serviceHost.Description.Behaviors.Add(serviceAuthorizationBehavior);
}
serviceAuthorizationBehavior.ExternalAuthorizationPolicies = new ReadOnlyCollection<IAuthorizationPolicy>(new IAuthorizationPolicy[] { new CustomAuthorizationPolicy_ClientService() });
((ServiceBehaviorAttribute)serviceHost.Description.Behaviors[typeof(ServiceBehaviorAttribute)]).MaxItemsInObjectGraph = 2147483647;
((ServiceBehaviorAttribute)serviceHost.Description.Behaviors[typeof(ServiceBehaviorAttribute)]).IncludeExceptionDetailInFaults = true;
ServiceThrottlingBehavior throttleBehavior = new ServiceThrottlingBehavior
{
MaxConcurrentCalls = 200,
MaxConcurrentInstances = 2147483647,
MaxConcurrentSessions = 2000,
};
serviceHost.Description.Behaviors.Add(throttleBehavior);
Console.WriteLine("Starting service...");
serviceHost.Open();
Console.WriteLine("Service started successfully (" + uri + ")");
return serviceHost;
}
catch(Exception ex)
In the IAuthorizationPolicy i set the principla like this just as before and it does break here :
var userContext = new UserContextOnService(new ClientIdentity { AuthenticationType = "regular", IsAuthenticated = true, Name = "username" }, currentAnvandare, LoginType.UsernamePassword);
userContext.OrbitToken = orbitToken;
evaluationContext.Properties["Principal"] = userContext;
SharedContext.Instance.AddUserContext(person.PersonId.ToString(), userContext);
The problem is that when I try to run this :
(UserContextOnService)Thread.CurrentPrincipal;
In the service method I get exception, the CurrentPrincipal is a WindowPrincipal?
I can get the correct Principal by using this code :
OperationContext.Current.ServiceSecurityContext.AuthorizationContext.Properties["Principal"]
But that would mean to change in MANY places where the context is fetched with just Thread.CurrentPrincipal.
I suspect that I have lost something in the configuration?
Edit : Have tried to set the Thread.CurrentPrincipal = userContext; in the Evaluate method but this does not help, the Thread.CurrentPrincipal if still a WindowsPrinciple? I suspect that the servicemethod is ending up on another thread then the one that executes the Evaluate.
When starting the service this needed to be set as well :
serviceAuthorizationBehavior.PrincipalPermissionMode = PrincipalPermissionMode.Custom;
serviceAuthorizationBehavior.ServiceAuthorizationManager = new CustomServiceAuthorizationManager();
This is done right above the following line :
serviceAuthorizationBehavior.ExternalAuthorizationPolicies = new ReadOnlyCollection<IAuthorizationPolicy>(new IAuthorizationPolicy[] { new CustomAuthorizationPolicy_ClientService() });

Call a WCF service with a HttpClient

I have to call a WCF service. The WCF service is on and I can edit its configuration.
I want to create a client that calls the service. I cannot add the service reference to my client, so I am trying to call it with a HttpClient.
The client side code:
using (var client = new HttpClient())
{
//soapString is my input class serialized
var content = new StringContent(soapString, Encoding.UTF8, "text/xml");
using (var postResponse = client.PostAsync("http://localhost:52937/Attempts.svc/", content).Result)
{
string postResult = postResponse.Content.ReadAsStringAsync().Result;
}
}
The server side code:
[ServiceContract]
public interface IAttempts
{
[OperationContract]
void ReceiveAttemptResult(ReceiveAttemptResultInput result);
}
public class Attempts : IAttempts
{
string _backendUrl;
public void ReceiveAttemptResult(ReceiveAttemptResultInput result)
{
//...
}
}
And in the end the web.config server side:
<system.serviceModel>
<services>
<service name="it.MC.Listeners.Attempts">
<endpoint address="" contract="it.MC.Listeners.IAttempts" binding="basicHttpBinding"/>
<endpoint address="mex" contract="IMetadataExchange" binding="mexHttpBinding"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
</system.serviceModel>
When I call the service, I just obtain an empty string and I cannot stop in debug inside the service... What's wrong?
Thank you
Just in case this bedevils anyone else. Thank you #Disappointed for your missing piece of the puzzle, it prompted me to run the thing in WCF Test Client with Fiddler open to see what I was missing:
HttpClient httpClient = new HttpClient();
httpClient.DefaultRequestHeaders.Add("SOAPAction", "http://tempuri.org/IMyService/Mymethod_Async");
string soapEnvelope = "<s:Envelope xmlns:s= \"http://schemas.xmlsoap.org/soap/envelope/\"><s:Body><Mymethod_Async xmlns=\"http://tempuri.org/\"/></s:Body></s:Envelope>";
var content = new StringContent(soapEnvelope, Encoding.UTF8, "text/xml");
HttpResponseMessage hrm = httpClient.PostAsync("http://MyService.MyDomain.com/MyService.svc", content).Result;

WCF Service not receiving data in POST

I have a WCF Service with a SOAP endpoint. I added a REST endpoint and the Get methods are working just fine. I am having trouble with a POST method which takes in an object and returns a different object. When I pass in my object, I get this error back:
"Message":"Object reference not set to an instance of an object."
Here's the code to call the service:
string URL = "http://qa.acct.webservice";
HttpClient client = new HttpClient();
client.BaseAddress = new Uri(URL);
// Add an Accept header for JSON format.
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
// HTTP POST
var request = new RequestGetInventory
{
BrandIDs = new string[] { "4", "42" },
AccountID = "9900003"
};
var resp = client.PostAsJsonAsync("/AxaptaService.svc/rest/GetInventory", request);
response = resp.Result;
if (response.IsSuccessStatusCode)
{
var temp = response.Content.ReadAsStringAsync().Result;
MessageBox.Show(temp); //error message received here.
}
The RequestGetInventory object is defined as follows:
[DataContract]
public class RequestGetInventory
{
[DataMember]
public string[] BrandIDs { get; set; }
[DataMember]
public string AccountID { get; set; }
}
The contract for the webservice is defined as follows:
[OperationContract]
[WebInvoke(Method = "POST",
RequestFormat = WebMessageFormat.Json,
BodyStyle = WebMessageBodyStyle.WrappedRequest,
ResponseFormat = WebMessageFormat.Json)]
ResponseGetInventory GetInventory(RequestGetInventory Request);
I tried playing around with the WebInvoke parameters, but received the same error message for all viable attempts.
And this is how my web.config is set up:
<system.serviceModel>
<services>
<service behaviorConfiguration="" name="Proj.AxaptaUS.WebService.AxaptaService">
<endpoint address="rest" behaviorConfiguration="webBehavior" binding="webHttpBinding" contract="Proj.Interfaces.Axapta3.IAxaptaService"></endpoint>
<endpoint address="" binding="basicHttpBinding" contract="Proj.Interfaces.Axapta3.IAxaptaService"></endpoint>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior>
<!-- To avoid disclosing metadata information, set the values below to false before deployment -->
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
<!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="webBehavior">
<webHttp helpEnabled="true" />
<enableWebScript/>
</behavior>
</endpointBehaviors>
</behaviors>
<protocolMapping>
<add binding="basicHttpsBinding" scheme="https" />
</protocolMapping>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
</system.serviceModel>
I am not entirely sure what I'm doing wrong because I can access this using SOAP just fine. It seems like it is not getting any values for the object which I passed in, thus causing the object reference error.
Any help would be greatly appreciated! Thanks!
#jstreet posted a comment which ended up working.
I changed BodyStyle = WebMessageBodyStyle.WrappedRequest to BodyStyle = WebMessageBodyStyle.Bare and removed <enableWebScript/> from config file.
After doing those things, it started to work correctly! thanks #jstreet!

WCF restful service not found

Hi all I'm trying to build WCF rest (Ajax enabled) I watch some tutorial in the YouTube as well as I read some questions about this topic in Stackoverflow.
I found some missing element in my web.config I thought the problem was completely fixed, but unfortunately I'm facing new problem now that is service not found.
this is web.config
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="ServiceBehavior">
<serviceDebug includeExceptionDetailInFaults="true"/>
<serviceMetadata httpGetEnabled="true"/>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="AjaxAndWCF.GetEmployeeAspNetAjaxBehavior">
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true"
multipleSiteBindingsEnabled="true" />
<services>
<service name="AjaxAndWCF.GetEmployee" behaviorConfiguration="ServiceBehavior">
<endpoint address="../GetEmployee.svc" behaviorConfiguration="AjaxAndWCF.GetEmployeeAspNetAjaxBehavior"
binding="webHttpBinding" contract="AjaxAndWCF.IGetEmployee" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:51520/GetEmployee.svc/"/>
</baseAddresses>
</host>
</service>
</services>
this is the service
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class GetEmployee : IGetEmployee
{
public Employee byId(int id)
{
Employee emp = new Employee();
String strcon = ConfigurationManager.ConnectionStrings["WCFTOAJAXT1ConnectionString"].ConnectionString;
using (SqlConnection con = new SqlConnection(strcon))
{
SqlCommand cmd = new SqlCommand("ProGetEmployeeById", con);
cmd.CommandType = CommandType.StoredProcedure;
SqlParameter parameter = new SqlParameter();
parameter.ParameterName = "#Id";
parameter.Value = id;
cmd.Parameters.Add(parameter);
con.Open();
SqlDataReader rdr = cmd.ExecuteReader();
while (rdr.Read())
{
emp.Id = Convert.ToInt32(rdr["Id"]);
emp.Name = rdr["Name"].ToString();
emp.Nationality = rdr["Nationality"].ToString();
emp.Email = rdr["Email"].ToString();
}
}
return emp;/*
return new Employee()
{
Id = 1,
Name = "test",
Nationality = "test",
Email ="test#test.com"
};*/
}
}
this is the service contract
[OperationContract]
[WebInvoke(UriTemplate = "/byId?id=id",
Method = "POST",
BodyStyle = WebMessageBodyStyle.WrappedRequest,
ResponseFormat = WebMessageFormat.Json)]
Employee byId(int id);
The Address in the endpoint is BASED off of the base address. Since you don't seem to have any other endpoints, you may as well hang your RESTFUL webservice off of the root address...blank out the address in your endpoint like below and let me know if this fixes it.
<service name="AjaxAndWCF.GetEmployee"
behaviorConfiguration="ServiceBehavior">
<endpoint address=""
behaviorConfiguration="AjaxAndWCF.GetEmployeeAspNetAjaxBehavior"
binding="webHttpBinding"
contract="AjaxAndWCF.IGetEmployee" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:51520/GetEmployee.svc/"/>
</baseAddresses>
</host>
</service>
And then your url will be http://localhost:51520/GetEmployee.svc/byid?id=5
I usually format my urls like "/byid/{id}" so I haven't tried to see if this method works, but I'm assuming you got that code from somewhere.

Categories