Fail to send image ( byte[] ) as parameter of WCF service - wcf

I wrote some service that have method that get image ( byte[] ) as parameter ( return void ).
I also wrote some client (client & server run on same machien - different sulotion - using IIS )that send the bitmap ( as byte[] ) to the service - and each time i try to send i get the exception:
An error occurred while receiving the HTTP response to http://localhost/WebService/Service.svc. This could be due to the service endpoint binding not using the HTTP protocol. This could also be due to an HTTP request context being aborted by the server (possibly due to the service shutting down)
I added one more method that get void and return int - and i can call this method with no problem.
What can be wrong ? Do i need to define something speciel in the client service reference ?
The service method
[ServiceContract]
**public interface IService**
{
[OperationContract]
void GetPic( byte[] pic );
}
**public class Service : IService**
{
public void GetPic( byte[] pic )
{
...
}
}
Web.config file:
<system.serviceModel>
<services>
<service behaviorConfiguration="ServiceBehavior" name="ServiceProxy.Service">
<endpoint
name="basicHttp"
address=""
binding="basicHttpBinding"
bindingConfiguration=""
contract="Contracts.IService">
</endpoint>
<endpoint
address="mex"
binding="mexHttpBinding"
contract="IMetadataExchange" >
</endpoint>
<host>
<baseAddresses>
<add baseAddress="http://localhost:8731/ServiceProxy/" />
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="ServiceBehavior">
<serviceMetadata httpGetEnabled="True"/>
<serviceDebug includeExceptionDetailInFaults="False" />
</behavior>
</serviceBehaviors>
</behaviors>

You must configure your binding on server to accept large messages. By default it accepts only messages up to 65KB and arrays with 16k elements = in your case bitmap which has size less then 16KB.
Use this in your web.config (server side):
<bindings>
<basicHttpBinding>
<binding name="myBinding" maxReceivedMessageSize="1000000">
<readerQuotas maxArrayLength="1000000" />
</binding>
</basicHttpBinding>
</bindings>
In your endpoint configuration reference this binding in bindingConfiguration attribute by setting it to myBinding.

Related

Error In consuming WCF services at client side end-point not found

I am working on ASP.NET WCF simple HelloWorld Example. I have successfully completed server side but I am getting issue while working on client side. I have used SVCUTIL.exe to generate proxy classes for me.
On debug I am getting following error;
An exception of type 'System.InvalidOperationException' occurred in System.ServiceModel.dll but was not handled in user code
Additional information: Could not find endpoint element with name 'WSHttpBinding_IHelloWorldService' and contract 'IHelloWorldService' 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.
another thing, can I use Channel Factory if I don't access to dll file from server, say If I got access to WSDL url link
On Client Side app.config
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="WSHttpBinding_IHelloWorldService" />
<binding name="WSHttpBinding_IHelloWorldServiceAsyn" />
</wsHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost:8087/CreditUnionServices/HelloWorldServices/HelloWorldService"
binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IHelloWorldService"
contract="IHelloWorldService" name="WSHttpBinding_IHelloWorldService">
<identity>
<userPrincipalName value="DESKTOP-G6LE8I4\Khurram Zahid" />
</identity>
</endpoint>
<endpoint address="http://localhost:8087/CreditUnionServices/HelloWorldServices/HelloWorldServiceAsyn"
binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IHelloWorldServiceAsyn"
contract="IHelloWorldServiceAsyn" name="WSHttpBinding_IHelloWorldServiceAsyn">
<identity>
<userPrincipalName value="xyz\abc" />
</identity>
</endpoint>
</client>
</system.serviceModel>
Client Proxy Channel Factory
public class HelloWorldClient
{
public string SendTestMessage(string name)
{
ChannelFactory<IHelloWorldService> _HelloWorldClientService = new ChannelFactory<IHelloWorldService>("WSHttpBinding_IHelloWorldService");
IHelloWorldService _HelloWorldChannelService = _HelloWorldClientService.CreateChannel();
var _returnMessage = _HelloWorldChannelService.GetMessage(name);
((IClientChannel)_HelloWorldChannelService).Close();
return _returnMessage;
}
}
Server side config file
<system.serviceModel>
<services>
<service name="App.Services.Managers.HelloWorldManager" behaviorConfiguration="DefaultServiceBehavior">
<host>
<baseAddresses>
<add baseAddress="http://localhost:8087/CreditUnionServices/HelloWorldServices"/>
</baseAddresses>
</host>
<endpoint address="HelloWorldService" binding="wsHttpBinding" contract="App.Services.Contracts.IHelloWorldService"></endpoint>
<endpoint address="HelloWorldServiceAsyn" binding="wsHttpBinding" contract="App.Services.Contracts.IHelloWorldServiceAsyn"></endpoint>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="DefaultServiceBehavior">
<serviceMetadata httpGetEnabled="True" httpsGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="False" />
</behavior>
</serviceBehaviors>
</behaviors>
Update Code
public static class HelloWorldClient
{
public static string SendTestMessage(string name)
{
HelloWorldServiceClient _helloWorldService = new HelloWorldServiceClient("WSHttpBinding_IHelloWorldService");
var _returnMessage = _helloWorldService.GetMessage("mr kz ....");
return _returnMessage;
}
}

WCF Discovery returns machine names in metadata (cannot be resolved)

So I have a WCF service hosted in IIS8 (Windows Server 2012). Here's the relevant part of the configuration file:
<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true"
multipleSiteBindingsEnabled="true" />
<services>
<service name="MovieCorner.DAL.Service.MovieCornerDalService">
<host>
<baseAddresses>
<add baseAddress="http://192.168.221.101/MovieCorner/" />
</baseAddresses>
</host>
<!-- Service Endpoints -->
<endpoint address="" binding="basicHttpBinding"
contract="MovieCorner.Commons.Services.IMovieCornerDalService">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<!-- Metadata Endpoints -->
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
<endpoint kind="udpDiscoveryEndpoint" />
</service>
</services>
<bindings>
<basicHttpBinding>
<binding maxBufferSize="2147483647" maxReceivedMessageSize="2147483647" />
</basicHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="True" httpsGetEnabled="True" />
<serviceDebug includeExceptionDetailInFaults="True" />
<serviceDiscovery />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
A simple service with a simple binding, and with a discovery endpoint. The service is up and running, everything works fine. Almost...
Here's the code I'm using on the client side (it's just a "unit" test):
var client = new DiscoveryClient(new UdpDiscoveryEndpoint());
var response = client.Find(new FindCriteria(typeof(IMovieCornerDalService)));
Assert.IsNotNull(response);
Assert.IsNotNull(response.Endpoints);
Assert.IsTrue(response.Endpoints.Count > 0);
foreach (var endpoint in response.Endpoints)
{
Console.WriteLine("Address: {0}; Contract: {1}", endpoint.Address, endpoint.ContractTypeNames[0]);
}
The code successfully finds the only running service. The output is the following:
Address: http://ws12-iis8/MovieCorner/MovieCornerDalService.svc;
Contract: http://tempuri.org/:IMovieCornerDalService
The address is returned with the machine name that hosts the service. After the discovery I want to use the service like this:
var endpoint = response.Endpoints[0];
var clientProxy = ChannelFactory<IMovieCornerDalService>.CreateChannel(new BasicHttpBinding(), endpoint.Address);
var user = clientProxy.RegisterUser("1234"); // problem
The actual method call throws an exception, and the inner exception is the following: System.Net.WebException: The remote name could not be resolved: 'ws12-iis8'
The "unit" test runs in my PC, the service is hosted in a VM. I can reach the service at the http://192.168.221.101/MovieCorner/MovieCornerDalService.svc address. But not with the machine name address.
What am I missing? What are my options? How can I retrieve the actual (private) IP of the service hosting VM? I searched for different metadata options, but I'm not a pro in the web world, so I don't know what I'm looking for.
If you need more information, let me know. Thanks for your time!

WCF Service host using ServiceHostFactory with Multiple Binding

I have created WCF service to host on IIS.
I am using ServiceHostFactory method to host my service(using Unity as DI).
I want to host my service using multiple binding, over the HTTP as well as over the TCP.
I tried giving base address, but its not taking. still giving me error as Service registered with HTTP schema.
Below code snippet might give you and idea.
public class MyServiceHostFactory : ServiceHostFactory
{
protected override ServiceHost CreateServiceHost(
Type serviceType, Uri[] baseAddresses)
{
MyServiceHost serviceHost = new MyServiceHost(serviceType, baseAddresses);
//configure container
MyFactory.Register();
return serviceHost;
}
}
Config file:
<system.serviceModel>
<services>
<service name="My.Service.MyService">
<host>
<baseAddresses>
<add baseAddress="http://localhost:9000/MyService/"/>
<add baseAddress="net.tcp://localhost:9001/MyService/"/>
</baseAddresses>
</host>
<endpoint address="Question" binding="basicHttpBinding" contract="My.Contract.IQuestionContract" />
<endpoint address="Answer" binding="basicHttpBinding" contract="My.Contract.IAnswerContract" />
<endpoint address="Question" binding="netTcpBinding" contract="My.Contract.IQuestionContract" />
<endpoint address="Answer" binding="netTcpBinding" contract="My.Contract.IAnswerContract" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="MyServicebehavior">
<serviceMetadata httpGetEnabled="True" httpsGetEnabled="True" />
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="True">
</serviceHostingEnvironment>
Can anyone suggest me what can be done?
Main thing,
Is it possible to host service using ServiceHostFactory with Multiple Binding?
If Yes, can anyone help me how?
I'd try to remove base net.tcp address and specify full address on endpoint.

Silverlight WCF call is too large for sharepoint wcf

I have a silverlight 4 project calling a WCF service deployed on sharepoint 2010.
There are two methods a get and and a save,
teh get works fine but the save returns a generic message "Not Found"
The save is passing a large object with 2 lists. If I reduce the size of the list it all works.
So I figure I have to increase the maxReceivedMessageSize, this is easily done on the silverlight side just edit ServiceReferences.ClientConfig.
however I dont know where to do it on teh server side
Where is the binding information on the shaprepoint webserver.
I've had a look in \inetpub\wwwroot\wss\VirtualDirectories\80\web.config and it isn't there.
is there an easy way to get the binding info from teh URL?
I tried to setup some bindings for it but I just get errors
my attempt is
<bindings>
<basicHttpBinding>
<binding name="MyDemoBinding">
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Ntlm" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="MyDemoBehavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service behaviorConfiguration="MyDemoBehavior" name="BEIM.Webservices.Service">
<endpoint address="" binding="basicHttpBinding" bindingConfiguration="MyDemoBinding" contract="BEIM.Webservices.IService">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<host>
<baseAddresses>
<add baseAddress=”http://localhost/_vti_bin/BEIM.Webservices” />
</baseAddresses>
</host>
</service>
</services>
got the answer from here
private static void ConfigureWebService()
{
SPWebService contentService = SPWebService.ContentService;
contentService.ClientRequestServiceSettings.MaxReceivedMessageSize = -1;
SPWcfServiceSettings wcfServiceSettings = new SPWcfServiceSettings();
wcfServiceSettings.ReaderQuotasMaxStringContentLength = 10485760;
wcfServiceSettings.ReaderQuotasMaxArrayLength = 2097152;
wcfServiceSettings.ReaderQuotasMaxBytesPerRead = 10485760;
wcfServiceSettings.MaxReceivedMessageSize = 10485760;
// must be in lower case
contentService.WcfServiceSettings["service.svc"] = wcfServiceSettings;
contentService.Update();
}
I just ran it from a console app

same app.config : wcftestclient work, selfHosting doesnot

i have the same app config on both programs
A - the service itself when i run it , wcf Test Client starts.
B - A self host program using -new ServiceHost(typeof(MyService)))
here it is :
<services>
<service name="MyNameSpace.MyService"
behaviorConfiguration="MyService.Service1Behavior">
<host>
<baseAddresses>
<add baseAddress="http://localhost:5999/MyService"/>
</baseAddresses>
</host>
<endpoint
binding="basicHttpBinding"
contract="StorageServiceInterface.IService1"
bindingConfiguration="MyBasicHttpBinding"
name="basicEndPoint">
<identity>
<dns value="localhost"/>
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services>
<bindings>
<basicHttpBinding>
<binding name="MyBasicHttpBinding">
<security mode="None">
<transport clientCredentialType="None" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="HeziService.Service1Behavior">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
the client Uses ClientBase<StorageServiceInterface.IService1>
Client app.config :
<system.serviceModel>
<client>
<endpoint address="http://myIp/MyService"
binding="basicHttpBinding"
contract="StorageServiceInterface.IService1">
</endpoint>
</client>
</system.serviceModel>
when i run the selfhost program and doing host.open()
it does open it, but when i try to call a method it tells me that :
"No connection could be made because the target machine actively refused it 10.0.0.1:5999"
ofcourse when the service run from the WCF Test Client, every thing working.
how could it be ??
thanks in advance
Just guessing - how about adding an address to your server side endpoint:
<endpoint address="" .... >
Yes, the base address basically defines the whole address - but you should still add the address to your service endpoint - even if it's empty.
something strange:
regards to marc_s that ask me to write my selfhost prog code..
i was using :
private void m_startServiceToolStripMenuItem_Click(object sender, EventArgs e)
{
using (Host = new ServiceHost(typeof(MyNameSpace.MyService)))
{
Host.Open();
}
}
before i've added it to the question i tried to change it without the using part :
private void m_startServiceToolStripMenuItem_Click(object sender, EventArgs e)
{
Host = new ServiceHost(typeof(yNameSpace.MyService));
Host.Open();
}
and now its working !!
but, somehow it worked before...
thank you all anyway :-)