how to bind endpoints? - wcf

although there are many posts about the same issue I still haven't figured out how to solve the problem regarding endpoints.
In the solution there are several projects and after reading about similar problems I edited the app.config file of the StartUp Project the following way:
<system.serviceModel>
<services>
...
<service name="LiveGames.Engine.LoginService">
<endpoint address="" name="ILoginService" binding="wsHttpBinding" contract="LiveGames.Entities.Interfaces.ILoginService">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:8732/LiveGames.Engine/LoginService/" />
</baseAddresses>
</host>
</service>
</services>
<client>
<endpoint address="http://localhost:8732/LiveGames.Engine/LoginService/"
binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_ILoginService" contract="LiveGames.Entities.Interfaces.ILoginService"
name="ILoginService" kind="" endpointConfiguration="">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
</client>
</system.serviceModel>
I created the Proxy class with the following methods:
public ChannelFactory<T> GetFactory<T>(string serviceName, out T channel)
{
ChannelFactory<T> factory = new ChannelFactory<T>(serviceName);
channel = factory.CreateChannel();
return factory;
}
public JSONUserLogin Login(string username, string password)
{
JSONUserLogin retval = new JSONUserLogin();
ILoginService sec = null;
ChannelFactory<ILoginService> factory = null;
try
{
using (factory = GetFactory<ILoginService>("ILoginService", out sec))
{
retval = sec.Login(username, password);
}
return retval;
}
catch (Exception ex)
{
return new JSONUserLogin();
}
finally
{
if (sec != null)
((IChannel)sec).Close();
if (factory != null)
factory.Close();
}
}
When serviceName="ILoginService" and the execution hits the line ChannelFactory<T> factory = new ChannelFactory<T>(serviceName);
it throws an exception:
System.InvalidOperationException: Could not find endpoint element with name 'ILoginService' and contract 'LiveGames.Entities.Interfaces.ILoginService' in the ServiceModel client configuration section. This might be because no configuration file was found for your application, or because no endpoint element matching this name could be found in the client element.
Does anyone know what could be wrong here and how to fix the problem?

Related

WCF service hangs when calling method, however method is working

Hello I'm having issue with my wcf service. I'm trying to call method which returns list of type object. I'm also using entity framework.
public IList<Product> GetAllProducts()
{
using (var db = new AuctionContext())
{
return db.Products.ToList();
}
}
</service>
<service name="AuctionSystem.WcfService.ProductService">
<endpoint address="" binding="wsDualHttpBinding" contract="AuctionSystem.WcfService.Contracts.IProductService">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:9993/Design_Time_Addresses/AuctionSystem.WcfService/ProductService/" />
</baseAddresses>
</host>
</service>
And contract :
[OperationContract]
IList<Product> GetAllProducts();
The method itself is working, but when I try to invoke this method on my wcf service UI it got stuck at "invoking service" I'm using wsdualhttpbinding.
Any ideas please?
EDIT: I realized in Product object I have virtual List, why is this List causing wcf to hang?
For all wondering why It was caused because of circular dependency.

Reduce repeated nested identity in WCF config

My web.config for my WCF app has a series of endpoints defined like so:
<system.serviceModel>
<services>
<service behaviorConfiguration="whatever" name="MyService">
<endpoint name="Endpoint1" address="" binding="customBinding" bindingConfiguration="HttpIssuedTokenBinding" contract="My.App.Contract1">
<identity>
<certificateReference findValue="cert name storeName="TrustedPeople" storeLocation="LocalMachine" x509FindType="FindBySubjectName" />
</identity>
</endpoint>
<endpoint name="Endpoint2" address="" binding="customBinding" bindingConfiguration="HttpIssuedTokenBinding" contract="My.App.Contract2">
<identity>
<certificateReference findValue="cert name storeName="TrustedPeople" storeLocation="LocalMachine" x509FindType="FindBySubjectName" />
</identity>
</endpoint>
<endpoint name="Endpoint3" address="" binding="customBinding" bindingConfiguration="HttpIssuedTokenBinding" contract="My.App.Contract3">
<identity>
<certificateReference findValue="cert name storeName="TrustedPeople" storeLocation="LocalMachine" x509FindType="FindBySubjectName" />
</identity>
</endpoint>
<endpoint name="Endpoint4" address="" binding="customBinding" bindingConfiguration="HttpIssuedTokenBinding" contract="My.App.Contract4">
<identity>
<certificateReference findValue="cert name storeName="TrustedPeople" storeLocation="LocalMachine" x509FindType="FindBySubjectName" />
</identity>
</endpoint>
What I would like to do is
<system.serviceModel>
<services>
<service behaviorConfiguration="whatever" name="MyService">
<endpoint name="Endpoint1" address="" binding="customBinding" bindingConfiguration="HttpIssuedTokenBinding" contract="My.App.Contract1" />
<endpoint name="Endpoint2" address="" binding="customBinding" bindingConfiguration="HttpIssuedTokenBinding" contract="My.App.Contract2" />
<endpoint name="Endpoint3" address="" binding="customBinding" bindingConfiguration="HttpIssuedTokenBinding" contract="My.App.Contract3" />
<endpoint name="Endpoint4" address="" binding="customBinding" bindingConfiguration="HttpIssuedTokenBinding" contract="My.App.Contract4" />
with a default identity definition specified once in another place (even just a top level in the system.serviceModel element).
Basically I want to DRY, because the config is consistent all the way throughout. What I need help from SO is where does one find the "default identity for all endpoints" configuration element. MSDN isn't giving a lot of help, and I'm not sure where to reflect the .NET libs to see how this is interpreted when web.configs are read in at app startup.
Summary
Use Standard Endpoints to create a custom endpoint with the appropriate identity information, which can be configured from the configuration file.
Detail
Thank you for the question!. The uniform configuration of WCF services to reduce the configuration overhead is something I've been meaning to look into, and your question gave me just the excuse to do it.
I tackled this using Standard Endpoints, which have been around since .NET 4. The bulk of the work is done by inheriting from StandardEndpointElement:
namespace WcfEx
{
public class X509EndpointElement : StandardEndpointElement
{
private static string _findValueKey = "findValue";
private static string _storeNameKey = "storeName";
private static string _storeLocationKey = "storeLocation";
private static string _x509FindTypeKey = "x509SearchType";
public virtual string FindValue
{
get { return base[_findValueKey] as string; }
set { base[_findValueKey] = value; }
}
public virtual StoreName StoreName
{
get { return this[_storeNameKey] is StoreName ? (StoreName) this[_storeNameKey] : (StoreName) 0; }
set { this[_storeNameKey] = value; }
}
public virtual StoreLocation StoreLocation
{
get
{
return this[_storeLocationKey] is StoreLocation
? (StoreLocation) this[_storeLocationKey]
: (StoreLocation) 0;
}
set { this[_storeLocationKey] = value; }
}
public virtual X509FindType X509FindType
{
get { return this[_x509FindTypeKey] is X509FindType ? (X509FindType) this[_x509FindTypeKey] : (X509FindType) 0; }
set { this[_x509FindTypeKey] = value; }
}
protected override ConfigurationPropertyCollection Properties
{
get
{
ConfigurationPropertyCollection properties = base.Properties;
properties.Add(new ConfigurationProperty(_findValueKey, typeof (string), null,
ConfigurationPropertyOptions.None));
properties.Add(new ConfigurationProperty(_storeNameKey, typeof (StoreName), null,
ConfigurationPropertyOptions.None));
properties.Add(new ConfigurationProperty(_storeLocationKey, typeof (StoreLocation), null,
ConfigurationPropertyOptions.None));
properties.Add(new ConfigurationProperty(_x509FindTypeKey, typeof (X509FindType), null,
ConfigurationPropertyOptions.None));
return properties;
}
}
protected override Type EndpointType
{
get { return typeof (ServiceEndpoint); }
}
protected override ServiceEndpoint CreateServiceEndpoint(ContractDescription contract)
{
return new ServiceEndpoint(contract);
}
protected override void OnApplyConfiguration(ServiceEndpoint endpoint,
ServiceEndpointElement serviceEndpointElement)
{
endpoint.Address = new EndpointAddress(endpoint.Address.Uri,
EndpointIdentity.CreateX509CertificateIdentity(
GetCertificateFromStore()));
}
protected override void OnApplyConfiguration(ServiceEndpoint endpoint,
ChannelEndpointElement channelEndpointElement)
{
endpoint.Address = new EndpointAddress(endpoint.Address.Uri,
EndpointIdentity.CreateX509CertificateIdentity(
GetCertificateFromStore()));
}
private X509Certificate2 GetCertificateFromStore()
{
var certificateStore = new X509Store(StoreName, StoreLocation);
certificateStore.Open(OpenFlags.ReadOnly);
var matchingCertificates = certificateStore.Certificates.Find(X509FindType, FindValue, false);
X509Certificate2 matchingCertificate = null;
if (matchingCertificates.Count > 0)
matchingCertificate = matchingCertificates[0];
else throw new InvalidOperationException("Could not find specified certificate");
certificateStore.Close();
return matchingCertificate;
}
protected override void OnInitializeAndValidate(ChannelEndpointElement channelEndpointElement)
{
}
protected override void OnInitializeAndValidate(ServiceEndpointElement serviceEndpointElement)
{
}
}
}
A quick summary of the above code:
This class can be made visible in the .config file - so it's properties can be set through configuration;
There are four properties that specify the parameters for selecting the X509 certificate;
At some point in the lifetime of this class, the endpoint address is set with the identity specified by a certificate satisfying the search criteria.
You need a collection class in which to hold elements of the above class:
namespace WcfEx
{
public class X509EndpointCollectionElement : StandardEndpointCollectionElement<ServiceEndpoint, X509EndpointElement>
{
}
}
The system.serviceModel section of the .config file looks like this:
<system.serviceModel>
<extensions>
<endpointExtensions>
<add name="x509Endpoint" type="WcfEx.X509EndpointCollectionElement, WcfEx, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/>
</endpointExtensions>
</extensions>
<standardEndpoints>
<x509Endpoint>
<standardEndpoint storeLocation="LocalMachine" storeName="TrustedPeople" findValue="cert name" x509SearchType="FindBySubjectName"/>
</x509Endpoint>
</standardEndpoints>
<services>
<service name="WcfHost.Service1">
<endpoint address="" binding="wsHttpBinding" contract="WcfHost.IService1" kind="x509Endpoint" >
</endpoint>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
Things to note:
Be very careful about the value of the type attribute here - it needs to be exactly the same as typeof (X509EndpointElement).AssemblyQualifiedName.
Once registered, we can add the relevant configuration to the standardEndpoints element.
We "tag" an endpoint as having the customisation by using the kind attribute.

WCF Web Service Hosted in SharePoint 2010 browser blank page response

I'm facing a problem with SharePoint 2010 custom web service.
The service is an SVC installed and deployed on the system: without particular configuration it works but I need to customize the web.config to achieve some security roles.
The problems is that when I try to invoke methods from browser the response is empty.
This is my web.config
<?xml version="1.0"?>
<configuration>
<system.serviceModel>
<services>
<service name="SharePointWCFService.GetListData"
behaviorConfiguration="WCFBasicHttpBinding.Service1Behavior">
<endpoint address="http://address" binding="basicHttpBinding" contract="SharePointWCFService.IGetListData">
<identity>
<dns value="localhost"/>
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
<endpoint address="http://address" binding="WebHttpBinding" contract="SharePointWCFService.IGetListData" >
<identity>
<dns value="localhost" />
</identity>
</endpoint>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="WCFBasicHttpBinding.Service1Behavior">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
This is the interface I'm implementing:
[ServiceContract]
public interface IGetListData
{
[OperationContract]
[WebInvoke(Method = "GET", BodyStyle = WebMessageBodyStyle.Bare, ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json)]
JSonResult GetJsonResponse(string data);
}
And this the class
[BasicHttpBindingServiceMetadataExchangeEndpointAttribute]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]
class GetListData : IGetListData
{
private const string Admin_Svc_GetListData = "Admin_Svc_GetListData";
public JSonResult GetJsonResponse(string data)
{
return new JSonResult()
{
Firstname = "MyFirstname",
Lastname = "MyLastname"
};
} // public JSonResult GetJsonResponse(string data)
Do I must declare something different at web.config side?

WCF and ef 4.0 performance is very bad .... Site works very slow

we have a project in which we have used WCF because we have multiple sites which pull up the same data .... We have used HTTPBinding in WCF and EF 4.0 to interact with the database .. When it was moved to production environment we found that the site was very slow .... Do you know any way how we could increase the performance drastically ... EF is causing a lot performance issues ... Please suggest next steps
Service Contract
[ServiceContract]
public interface ICommonService
{
[OperationContract]
LoginDTO AuthenticateUser(string userName, string password, int ownerId);
}
<service name="MyService.Services.CommonService">
<endpoint binding="basicHttpBinding" bindingConfiguration=""
name="CommonServiceEndpoint" contract="MyService.Services.Contracts.ICommonService">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:8732/Design_Time_Addresses/MyService.Services/ICommonService/" />
</baseAddresses>
</host>
</service>
We have introduced indexing but it doesn't increase performance so much
using (MyService.DataAccess.MyService_RedesignEntities context = new MyService_RedesignEntities())
{
context.ContextOptions.ProxyCreationEnabled = false;
context.ContextOptions.LazyLoadingEnabled = false;
ObjectParameter StrOutput = new ObjectParameter("chvnOutputMesage", SqlDbType.NVarChar);
objResult = context.spAuthenticateUser(ownerId, userName, encryptedPassword).FirstOrDefault();
return objResult;
}

How do I set WCF endpoint identity configuration programmatically?

How do I set dns programmatically like doing for other configuration as below?
<endpoint address="https://admin.icafems.com/Services/EasyStartTrackingService.svc"
binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IEasyStartTrackingService"
contract="ES_Service.IEasyStartTrackingService" name="WSHttpBinding_IEasyStartTrackingService">
<identity>
<dns value="admin.icafems.com" />
</identity>
</endpoint>
ServiceClient.Endpoint.Address = new EndpointAddress(ServiceURL);
ServiceClient.Endpoint.Binding = binding;
ServiceClient.Endpoint.Name = "BasicHttpBinding_ILearningSuiteService";
You pass an EndpointIdentity to the constructor of the EndpointAddress
http://msdn.microsoft.com/en-us/library/bb628618.aspx