So, I've made this web service(well WCF Service I guess) that inputs some parameters and returns a json object. This works pretty well.
But now I want to make some changes to the client.
Currently I just have a button, some textboxes for inputs, and a textarea.
The button looks like this:
ServiceReference1.Service1Client sc = new ServiceReference1.Service1Client();
protected void Button11_Click(object sender, EventArgs e)
{
int? i;
if (tbSagsNr.Text != "")
{
i = Convert.ToInt32(tbPOSTUdlSag.Text);
}
else
{
i = null;
}
string s = tbFacilitet.Text;
string a1 = tbAdresse1.Text;
string a2 = tbAdresse2.Text;
string p = tbPostNr.Text;
string json = sc.HouseSearch(i, s, a1, a2, p);
TextArea1.InnerText = json;
}
What do I do if I want to call the web service through the url instead? I'm thinking it should look something like this, depending on what parameters I use:
http://localhost:58637/Default.aspx/Service1.svc/HouseSearch?vSagsNr=5
Instead of textboxes and all that it should just print the json string directly on the screen.
I'm pretty new at making web services and I feel like I've kinda just been bumbling my way so far.
IService1:
[OperationContract()]
[WebInvoke(Method = "POST", ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Bare, UriTemplate = "HouseSearch")]
string HouseSearch(int? vSagsNr, string vFacilitet, string vAdresse1, string vAdresse2, string vPostNr);
Edit: Actually it should look more like this probably:
http://localhost:58637/WCFTest3/Service1.svc/HouseSearch?vSagsnr=5
Edit: My webconfig now looks like this:
<?xml version="1.0"?>
<configuration>
<appSettings>
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
</appSettings>
<system.web>
<compilation debug="true" targetFramework="4.6.1" />
<httpRuntime requestPathInvalidCharacters="" requestValidationMode="2.0" targetFramework="4.6.1"/>
<pages validateRequest="false" />
</system.web>
<system.serviceModel>
<services>
<service behaviorConfiguration="WCFTest3_Behavior" name="WCFTest3.Service1">
<endpoint
address =""
binding="webHttpBinding"
bindingConfiguration="webHttpEndpointBinding"
name="WCFTest3.Service1"
contract="WCFTest3.IService1"
behaviorConfiguration="web"/>
<endpoint address="mex" binding="mexHttpBinding" bindingConfiguration="" name="mexEndPoint" contract="IMetadataExchange"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="WCFTest3_Behavior">
<!-- To avoid disclosing metadata information, set the values below to false before deployment -->
<serviceMetadata httpGetEnabled="false" />
<!-- 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="true"/>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="web">
<webHttp />
</behavior>
</endpointBehaviors>
</behaviors>
<bindings>
<webHttpBinding>
<binding name="webHttpEndpointBinding">
<security mode="Transport">
<transport clientCredentialType="Windows" />
</security>
</binding>
</webHttpBinding>
</bindings>
<protocolMapping>
<add binding="webHttpBinding" scheme="http" />
</protocolMapping>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true"/>
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
<!--
To browse web app root directory during debugging, set the value below to true.
Set to false before deployment to avoid disclosing web app folder information.
-->
<directoryBrowse enabled="true"/>
</system.webServer>
<connectionStrings>
<add
name="UnikBoligCon"
connectionString="server=??;database=??;user=??;password=??"
providerName="System.Data.SqlClient"
/>
</connectionStrings>
</configuration>
But I get this error:
No base address found that matches the https form for the endpoint with the WebHttpBinding link. Registered base address schemas are [http].
Edit: Oh wait I guess I need to fill in the adress, services in the webconfig now looks like this
<services>
<service behaviorConfiguration="WCFTest3_Behavior" name="WCFTest3.Service1">
<endpoint
address ="http://localhost:58532/Service1.svc"
binding="webHttpBinding"
bindingConfiguration="webHttpEndpointBinding"
name="WCFTest3.Service1"
contract="WCFTest3.IService1"
behaviorConfiguration="web"/>
<endpoint address="mex" binding="mexHttpBinding" bindingConfiguration="" name="mexEndPoint" contract="IMetadataExchange"/>
</service>
</services>
And I've gotten rid of "multipleSiteBindingsEnabled="true"" because it threw an error and I don't think I need it.
Now getting this error though:
The authentication schemes configured on the host (Anonymous) do not allow those configured on the binding WebHttpBinding (“Anonymous”). Please ensure that the SecurityMode is set to Transport or TransportCredentialOnly. Additionally, this may be resolved by changing the authentication schemes for this application through the IIS management tool, through the ServiceHost.Authentication.AuthenticationSchemes property, in the application configuration file at the element, by updating the ClientCredentialType property on the binding, or by adjusting the AuthenticationScheme property on the HttpTransportBindingElement.
I have done something much the same as you described. A WCF service that can be switched (by changing the web.config) to serve Http, NetTCP, or REST. It was easy enough to get Http and NetTCP configs to sit side by side, but I was unable to figure out how to incorporate the REST config with the other two, so I kept them separate (and my requirements didn't call for a REST api, I just wanted to do it anyway).
My Operation Contract is:
[OperationContract]
[
WebInvoke(Method = "GET",
BodyStyle = WebMessageBodyStyle.Wrapped,
RequestFormat = WebMessageFormat.Json,
ResponseFormat = WebMessageFormat.Json,
UriTemplate = "TestMethod/{applicationCode}/?ignoreStatus={ignoreStatus}&logonName={logonName}&userProfileId={userProfileId}")
]
String TestMethod(String applicationCode, Boolean ignoreStatus = false, String logonName = "", String userProfileId = "");
Which can be called via a Url (tested using an Internet Browser).
http://localhost/JayVServerV2/DataAccess/DataAccess.svc/TestMethod/Tom?ignoreStatus=true&logonName=JayV&userProfileId
The most important part of the solution was getting the Web.Config setup correctly. So, I have included the whole of my Web.Config for you to see how I did it.
<?xml version="1.0"?>
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.5.2"/>
<httpRuntime targetFramework="4.5"/>
<authentication mode="Windows"/>
<authorization>
<allow users="*"/>
</authorization>
<identity impersonate="false"/>
</system.web>
<system.serviceModel>
<services>
<service behaviorConfiguration="JayVServer_Behavior" name="JayVServerV2.DataAccess.DataAccess">
<endpoint
address =""
binding="webHttpBinding"
bindingConfiguration="webHttpEndpointBinding"
name="RestJayVServerV2.DataAccess.DataAccess"
contract="DataServerV2.DAtaAccess.IDataAccess"
behaviorConfiguration="web"/>
<endpoint address="mex" binding="mexHttpBinding" bindingConfiguration="" name="mexEndPoint" contract="IMetadataExchange"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="JayVServer_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="true"/>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="web">
<webHttp />
</behavior>
</endpointBehaviors>
</behaviors>
<bindings>
<webHttpBinding>
<binding name="webHttpEndpointBinding">
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Windows" />
</security>
</binding>
</webHttpBinding>
</bindings>
<protocolMapping>
<add binding="webHttpBinding" scheme="http" />
</protocolMapping>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true"/>
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
<directoryBrowse enabled="true"/>
</system.webServer>
</configuration>
Related
I have created a WCF Web Service. Which have some [OperationContract] with GET request and one [OperationContract] with POST request. The problem is that, the POST [OperationContract] works fine with localhost but when published on IIS it returns "Endpoint not found" error.
Here is my WCF Service Interface
Interface IService1.cs
[OperationContract]
[WebInvoke(Method = "POST", UriTemplate = "UploadImage", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Wrapped)]
string UploadImage(Stream stream);
OR (Alternatively)
When I call this POST [OperationContract] with this URL: http://localhost:5031/Service1.svc/UploadImage , Then it works fine.
BUT
when I call it with URL: http://IP/Wcfservice1/Service1.svc/UploadImage , Then it returns "Endpoint not found"
Here is my Interface Implementation:
IService1.svc.cs
public class Service : IService
{
public string UploadImage(Stream stream)
{
Random r = new Random();
int index = r.Next(0, 99);
System.Drawing.Bitmap imag = new System.Drawing.Bitmap(stream);
byte[] imagedata = ImageToByte(imag);
//Write code here to Save byte code to database..
stream.Read(imagedata, 0, imagedata.Length);
FileStream f = new FileStream(#"E:\Studies\Uploaded Images\TestProfileImage" + index + ".jpg", FileMode.OpenOrCreate);
f.Write(imagedata, 0, imagedata.Length);
f.Close();
stream.Close();
return "Success";
}
}
public static byte[] ImageToByte(System.Drawing.Image img)
{
ImageConverter converter = new ImageConverter();
return (byte[])converter.ConvertTo(img, typeof(byte[]));
}
and in my web.config I have the following:
Web.config
<?xml version="1.0"?>
<configuration>
<appSettings>
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
</appSettings>
<system.web>
<compilation debug="true" targetFramework="4.5" />
<httpRuntime targetFramework="4.5" />
</system.web>
<system.serviceModel>
<bindings>
<webHttpBinding>
<binding name="WcfService1.WebHttp" maxBufferSize="2147483647"
maxBufferPoolSize="2147483647"
maxReceivedMessageSize="2147483647"
transferMode="Streamed"
sendTimeout="00:05:00">
<readerQuotas maxDepth="2147483647"
maxStringContentLength="2147483647"
maxArrayLength="2147483647"
maxBytesPerRead="2147483647"
maxNameTableCharCount="2147483647"/>
<security mode="None" />
</binding>
</webHttpBinding>
</bindings>
<services>
<service name="WcfService1.Service1">
<endpoint address="" behaviorConfiguration="myweb" contract="WcfService1.IService1" binding="webHttpBinding" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:5031/Service1.svc" />
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<endpointBehaviors>
<behavior name ="myweb">
<webHttp/>
</behavior>
</endpointBehaviors>
<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="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
<protocolMapping>
<add binding="basicHttpBinding" scheme="http" />
<add binding="basicHttpsBinding" scheme="https" />
<add binding="webHttpBinding" scheme="http"/>
</protocolMapping>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
<!--
To browse web app root directory during debugging, set the value below to true.
Set to false before deployment to avoid disclosing web app folder information.
-->
<directoryBrowse enabled="true"/>
<security>
<requestFiltering>
<requestLimits maxAllowedContentLength="102400000" />
</requestFiltering>
</security>
</system.webServer>
</configuration>
Please let me know, what's the problem here and what do i need to fix.
Thanks you for taking time to have a look on this post.
Thanks
http://192.168.1.5/Service1.svc/UploadImage .
instead of http://192.168.1.5/Wcfservice1/Service1.svc/UploadImage
hopefully it might work.
would you please remove the host section from your config file and try this http://IP/Wcfservice1/Service1.svc/UploadImage again?
UPDATE:
try to enable the service help page. then we can find out the endpoint adress. add this section to tour config:
<endpointBehaviors>
<behavior name="myweb">
<webHttp helpEnabled="true" defaultBodyStyle="Bare" defaultOutgoingResponseFormat="Json" automaticFormatSelectionEnabled="true" />
</behavior>
</endpointBehaviors>
I have a WCF service application set up so when I call the address it just returns true.
IRemoteService.cs
[OperationContract]
[WebInvoke(Method = "GET", ResponseFormat = WebMessageFormat.Json,
BodyStyle = WebMessageBodyStyle.Wrapped,
UriTemplate = "ValidationResult/")]
bool ValidationResult();
RemoteService.svc.cs
namespace RemoteService
{
public class RemoteService : IRemoteService
{
public bool ValidationResult()
{
return true;
//throw new NotImplementedException();
}
}
}
I have added an application on IIS and now I can access the service on the following url :
https://localhost/ValidationServiceApp/RemoteService.svc/validationresult/
This returns :
{"ValidationResultResult":true}
Works great. But when I run the following powershell script, I cant access the service :
$url = "https://localhost/ValidationServiceApp/SASRemoteService.svc/validationresult/"
$result = Invoke-RestMethod -Method GET -Uri $url
Write-Host $result
I must point out, I have tried on a client application called 'I'm only resting' and this returns whats expected. So I think it must be something to do with powershell. Either I haven't allowed something in the web.config file or some setting missing in powershell. I have also tried to ignore certificate errors on powershell. This didn't help.
Error from powershell :
Invoke-RestMethod : The underlying connection was closed: An unexpected error occurred on a send.
At line:18 char:11
+ $result = Invoke-RestMethod -Method GET -Uri $url
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-RestMethod], WebException
+ FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand
Here is the web.config file for the service :
<?xml version="1.0"?>
<configuration>
<appSettings>
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true"/>
</appSettings>
<system.web>
<compilation debug="true" targetFramework="4.6"/>
<httpRuntime targetFramework="4.6"/>
<httpModules>
<add name="ApplicationInsightsWebTracking" type="Microsoft.ApplicationInsights.Web.ApplicationInsightsHttpModule, Microsoft.AI.Web"/>
</httpModules>
</system.web>
<system.serviceModel>
<bindings>
<webHttpBinding>
<binding name="webHttpTransportSecurity">
<security mode="Transport">
<transport clientCredentialType="None" proxyCredentialType="None" />
</security>
</binding>
</webHttpBinding>
</bindings>
<services>
<service name="RemoteService.RemoteService" behaviorConfiguration="ServiceBehaviour">
<endpoint address =""
binding="webHttpBinding"
contract="RemoteService.IRemoteService"
bindingConfiguration="webHttpTransportSecurity"
behaviorConfiguration="web" />
<endpoint address="mex"
binding="mexHttpsBinding"
contract="IMetadataExchange" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="ServiceBehaviour">
<!-- To avoid disclosing metadata information, set the values below to false before deployment -->
<serviceMetadata httpGetEnabled="false" 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="web">
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
<protocolMapping>
<add binding="webHttpBinding" scheme="https"/>
</protocolMapping>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true"/>
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true">
<remove name="ApplicationInsightsWebTracking"/>
<add name="ApplicationInsightsWebTracking" type="Microsoft.ApplicationInsights.Web.ApplicationInsightsHttpModule, Microsoft.AI.Web"
preCondition="managedHandler"/>
</modules>
<!--
To browse web app root directory during debugging, set the value below to true.
Set to false before deployment to avoid disclosing web app folder information.
-->
<directoryBrowse enabled="true"/>
<validation validateIntegratedModeConfiguration="false"/>
</system.webServer>
</configuration>
Managed to find the problem.
I needed to edit permissions on the hosted service in IIS. So I added Users ({pcname}/Users) to the list of allowed users.
I would delete the question, but perhaps this may help someone in the future :)
My web.config for WCF service looks like below
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0" />
</system.web>
<system.serviceModel>
<services>
<service name="WcfService1.Service1">
<endpoint address="" binding="basicHttpBinding"
bindingConfiguration="" name="service1Endpoint"
contract="WcfService1.IService1" />
<endpoint address=""
behaviorConfiguration="WcfService1.AjaxAspNetAjaxBehavior"
binding="" contract="WcfService1.IService1" />
</service>
</services>
<bindings>
<basicHttpBinding>
<binding name="service1Endpoint" />
</basicHttpBinding>
<webHttpBinding>
<binding name="webHttpBinding" />
</webHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost:2393/Service1.svc"
binding="basicHttpBinding"
bindingConfiguration="service1Endpoint"
contract="ServiceReference1.IService1"
name="service1Endpoint" />
<endpoint address="http://localhost:2393/Service1.svc"
behaviorConfiguration="WcfService1.AjaxAspNetAjaxBehavior"
binding="webHttpBinding" contract="ServiceReference1.IService1"
/>
</client>
<behaviors>
<serviceBehaviors>
<behavior>
<!-- To avoid disclosing metadata information, set the value below to
false and remove the metadata endpoint above before deployment -->
<serviceMetadata httpGetEnabled="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="WcfService1.AjaxAspNetAjaxBehavior">
<enableWebScript />
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
</system.webServer>
</configuration>
I have another simple aspx page created to test whether service is accessible or not. But when I am trying to run this service error displayed is Failed to add a service. Service metadata may not be accessible. Make sure your service is running and exposing metadata. Can anyone tell me how to resolve this error.
Thanks in advance.
My web service and contract is as below
namespace WcfService1
{
[AspNetCompatibilityRequirements(RequirementsMode =
AspNetCompatibilityRequirementsMode.Allowed)]
public class Service1 : IService1
{
public string GetData(int value)
{
return string.Format("You entered: {0}", value);
}
}
}
Contract looks like below
namespace WcfService1
{
[ServiceContract]
public interface IService1
{
[OperationContract]
[WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.Wrapped,
ResponseFormat = WebMessageFormat.Json)]
string GetData(int value);
}
}
You need a mex service endpoint to allow metadata to be exposed. Add a new endpoint under service node like:
<endpoint address="mex" binding="mexHttpBinding" name="MetadataEndpoint"
contract="IMetadataExchange" />
Read more about Metadata Exchange Endpoint here:
http://www.wcftutorial.net/Metadata-Exchange-Endpoint.aspx
I have a WCF service that works as expected when providing proper credentials.
When I try to consume the service with wrong credentials, the service sends an MessageSecurityException error as expected, and I receive an error: "MessageSecurityException was unhandled by user code".
I'm not sure how to handle this exception, since it is raised in the Reference.cs file that is auto-generated and not really under my control:
References.cs
public string EndLogin(System.IAsyncResult result) {
object[] _args = new object[0];
string _result = ((string)(base.EndInvoke("Login", _args, result))); //Here is the error raised
return _result;
}
Ideal would be to check if the service has accepted the credentials instead of relying on an error raised, but have no idea how to check this.
Hope someone can help me, so my App don't have to crash on each wrong login ;)
Web.config : Service:
<?xml version="1.0"?>
<configuration>
<appSettings>
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
</appSettings>
<system.web>
<compilation debug="true" targetFramework="4.5" />
<httpRuntime targetFramework="4.5"/>
</system.web>
<system.serviceModel>
<services>
<service name="BiBasicService.SalesMarketingService">
<endpoint address="" binding="basicHttpBinding" bindingConfiguration="basicHttpBinding"
contract="BiBasicService.ISalesMarketingService" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
</services>
<bindings>
<basicHttpBinding>
<binding name="basicHttpBinding">
<security mode="TransportWithMessageCredential">
<message clientCredentialType="UserName" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior>
<!-- To avoid disclosing metadata information, set the values below to false before deployment -->
<serviceMetadata httpsGetEnabled="true" httpGetEnabled="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"/>
<!-- To enable custom Role validation -->
<serviceAuthorization principalPermissionMode="Custom">
<authorizationPolicies>
<add policyType="BiBasicService.Security.AuthorizationPolicy, BiBasicService" />
</authorizationPolicies>
</serviceAuthorization>
<!-- To enable custom Username and Password validator-->
<serviceCredentials>
<userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="BiBasicService.Security.CustomValidator, BiBasicService"/>
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
<protocolMapping>
<add binding="basicHttpsBinding" scheme="https" />
</protocolMapping>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="false" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
<!--
To browse web app root directory during debugging, set the value below to true.
Set to false before deployment to avoid disclosing web app folder information.
-->
<directoryBrowse enabled="true"/>
</system.webServer>
</configuration>
ServiceReferences.ClientConfig : Client:
<configuration>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_ISalesMarketingService" maxBufferSize="2147483647"
maxReceivedMessageSize="2147483647">
<security mode="TransportWithMessageCredential" />
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="https://PUBLICDOMAIN/BasicHttp/SalesMarketingService.svc"
binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_ISalesMarketingService"
contract="ServiceReference1.ISalesMarketingService" name="BasicHttpBinding_ISalesMarketingService" />
</client>
</system.serviceModel>
</configuration>
The MessageSecurityException: it's a binding error.
Make sure the binding configuration on server side and client side must match.
Please post the server side web.config and client side web.config
You may want to look into the IErrorHandler interface, which would allow you to handle the exception at a more “global level”. The IErrorHandler is an extension that allows explicitly control the behavior of the application when an exception is thrown, implement the IErrorHandler interface and add it to the Dispatcher’s ErrorHandlers property. IErrorHandler enables you to explicitly control the SOAP fault generated, decide whether to send it back to the client, and perform associated tasks, such as logging. Error handlers are called in the order in which they were added to the ErrorHandlers property.
http://msdn.microsoft.com/en-us/library/system.servicemodel.dispatcher.ierrorhandler.aspx
http://blogs.msdn.com/b/carlosfigueira/archive/2011/06/07/wcf-extensibility-ierrorhandler.aspx
I created a new Test WCF Application. It runs fine with the Simple GetData method with the WCF Test Client when I run the solution in Visual Studio. However I now want to add a Service Reference to an external WCF Service so that I can talk to it from this Web Service. So the interface for me Service1 now looks like:
public interface IService1 : MyExternalService
Then on my service class where I have the simple GetData I can hit Implement Interfaces and I see all the methods for the External Web Service created:
public class Service1 : IService1
{
public string GetData(int value)
{
return string.Format("You entered: {0}", value);
}
public string ExternalMethod1(string a, string b)
{
throw new NotImplementedException();
}
//etc
However if I try to run this with the WCF Test Client - I get the following error message - Failed to add a service. Service metadata may not be accessible. Make sure your service is running and exposing metadata.
After I included the External Service Ref it updated my web.config to as below (note some actual urls scrubbed)
<configuration>
<appSettings>
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
</appSettings>
<system.web>
<compilation debug="true" targetFramework="4.5" />
<httpRuntime targetFramework="4.5"/>
</system.web>
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="WSHttpBinding_IExternalService">
<security>
<message clientCredentialType="Certificate" />
</security>
</binding>
<binding name="WSHttpBinding_IExternalService1">
<security>
<message clientCredentialType="Certificate" negotiateServiceCredential="false"
algorithmSuite="Basic128" establishSecurityContext="false" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<client>
<endpoint address="http://service.com/ExternalService/ExternalService.svc"
binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IExternalService"
contract="ExternalService.IExternalService" name="WSHttpBinding_IExternalService">
<identity>
<dns value="service.com" />
</identity>
</endpoint>
<endpoint address="http://service.com/ExternalService/ExternalService.svc/Java"
binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IExternalService1"
contract="ExternalService.IExternalService" name="WSHttpBinding_IExternalService1">
<identity>
<dns value="service.com" />
</identity>
</endpoint>
</client>
<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>
</behaviors>
<protocolMapping>
<add binding="basicHttpsBinding" scheme="https" />
</protocolMapping>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
<!--
To browse web app root directory during debugging, set the value below to true.
Set to false before deployment to avoid disclosing web app folder information.
-->
<directoryBrowse enabled="true"/>
</system.webServer>
</configuration>
You need to add a metadata exchange endpoint to the first service
<services>
<service name="MyService.MyService" behaviorConfiguration="metadataBehavior">
<endpoint
address="http://localhost/MyService.svc"
binding="customBinding" bindingConfiguration="jsonpBinding"
behaviorConfiguration="MyService.MyService"
contract="MyService.IMyService"/>
<endpoint
address="mex"
binding="mexHttpBinding"
contract="IMetadataExchange"/>
</service>
</services>
This thread seems to discuss the same issue WCF Test Client : Failed to add a service. Service metadata may not be accessible. Make sure your service is running and exposing metadata