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?
Related
Client side Code
I have created web application and added service reference to the Client Project
I tried creating a client Object like this:
Service1Client a = new Service1Client();
but getting an error message :
Could not find default endpoint element that references contract 'ServiceReference_test.IService1' 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 contract could be found in the client element.
Could you please let me know what mistake am I doing, I am new to WCF please help me
WCF service which returns JSON Format:
namespace WcfService1
{
public class Service1 : IService1
{
public string GetData(string Id)
{
return ("You entered: " + Id);
}
}
}
namespace WcfService1
{
[ServiceContract]
public interface IService1
{
[OperationContract]
[WebInvoke(Method = "GET", UriTemplate = "/GetData/{Id}",
RequestFormat = WebMessageFormat.Json,
ResponseFormat = WebMessageFormat.Json,
BodyStyle = WebMessageBodyStyle.Wrapped
)]
string GetData(string Id);
// TODO: Add your service operations here
}
}
Web.Config file
<system.serviceModel>
<services>
<service name="WcfService1.Service1" behaviorConfiguration="ServiceBehaviour">
<endpoint address="" behaviorConfiguration="web" binding="webHttpBinding" contract="WcfService1.IService1"/>
<endpoint contract="IMetadataExchange" binding="mexHttpBinding" address="mex"/>
</service>
</services>
<behaviors>
<endpointBehaviors>
<behavior name="web">
<webHttp helpEnabled="true" automaticFormatSelectionEnabled="false" />
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="ServiceBehaviour">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
<!--<protocolMapping>
<add binding="basicHttpsBinding" scheme="https" />
</protocolMapping>-->
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
</system.serviceModel>
You should add following tags in your client App.config or Web.config:
<system.serviceModel>
<bindings>
<webHttpBinding>
<binding name="WebHttpBinding" />
</webHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost:8733/Design_Time_Addresses/fine_service/FineService/soap"
binding="webHttpBinding" bindingConfiguration="WebHttpBinding"
contract="ServiceReference1.IService1" name="WebHttpBinding" />
</client>
</system.serviceModel>
if you have this tags in your cofig file then make sure that client endpoint contract name should be the same as it is in your service endpoint. In your case contract name is IService1
EDIT:
also see this
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;
}
}
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.
Um quite new to WCF . I think I have messed up a bit. So this is what I did so far and I ve hosted my WCF service in IIS
First the Contracts
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;
using YangkeeServer.dto;
namespace YangkeeServer
{
public class Service1 : IService1
{
[WebInvoke(Method = "GET", ResponseFormat = WebMessageFormat.Json, UriTemplate = "single")]
public YangkeeTrailerDTO getTrailor()
{
return new YangkeeTrailerDTO()
{
loanFrom = "heaven"
};
}
[WebInvoke(Method = "GET",
ResponseFormat = WebMessageFormat.Json,
UriTemplate = "datum/{id}")]
public Test getName(string id)
{
return new Test()
{
Id = Convert.ToInt32(id) * 12,
Name = "Leo Messi"
};
}
}
}
and this is my web.config file
<?xml version="1.0"?>
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0" />
</system.web>
<system.serviceModel>
<services>
<service name="YangkeeServer.Service1">
<endpoint
contract="YangkeeServer.IService1"
binding="webHttpBinding"
behaviorConfiguration="WebHttp"
address="http://localhost:7000/Service1.svc">
</endpoint>
</service>
<service name="YangkeeServer.Service2">
<endpoint
contract="YangkeeServer.IService2"
binding="webHttpBinding"
behaviorConfiguration="WebHttp"
address="http://localhost:7000/Service2.svc">
</endpoint>
</service>
<service name="YangkeeServer.YangkeeTrailer">
<endpoint
contract="YangkeeServer.IYangkeeTrailor"
binding="webHttpBinding"
behaviorConfiguration="WebHttp"
address="http://localhost:7000/YangkeeTrailor.svc">
</endpoint>
</service>
</services>
<behaviors>
<endpointBehaviors>
<behavior name="WebHttp">
<webHttp />
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
</system.webServer>
</configuration>
and um using this urlhttp://localhost:7000/Service1.svc and um getting this error
Server Error in '/' Application.
When 'system.serviceModel/serviceHostingEnvironment/multipleSiteBindingsEnabled' is set to true in configuration, the endpoints are required to specify a relative address. If you are specifying a relative listen URI on the endpoint, then the address can be absolute. To fix this problem, specify a relative uri for endpoint 'http://localhost:7000/Service1.svc'.
can any one tell me where did I do wrong? Thank you in advance.
Set the service endpoint address to just the service filename (this is the relative part):
address="Service1.svc"
or set the address to blank for each endpoint (I don't think its needed when hosting in the development environment or in IIS)
address=""
See this answer to another question
The relevant part is:
the virtual directory (in IIS) where your *.svc file exists defines your service endpoint's address.
To fix this error, I added... listenUri="/" ... to the service endpoint.
Example:
<service name="_name_">
<endpoint address="http://localhost:_port_/.../_servicename_.svc"
name="_servicename_Endpoint"
binding="basicHttpBinding"
bindingConfiguration="GenericServiceBinding"
contract="_contractpath_._contractname_"
listenUri="/" />
</service>
MSDN: Multiple Endpoints at a Single ListenUri
This works for me:
1. Insert this lines inside service:
<host>
<baseAddresses>
<add baseAddress="http://localhost:7000/Service1.svc" />
</baseAddresses>
</host>
2. Set the value of address as bellow:
address=""
The full code:
<service name="YangkeeServer.Service1">
<host>
<baseAddresses>
<add baseAddress="http://localhost:7000/Service1.svc" />
</baseAddresses>
</host>
<endpoint
contract="YangkeeServer.IService1"
binding="webHttpBinding"
behaviorConfiguration="WebHttp"
address="">
</endpoint>
</service>
I'm trying to process a post by a third party server (Paypal) processed by my server through a WCF (.Net 3.5 SP1) service. All I need is to get and process the values with the query string. This sounds incredibly easy, but after a weekend, I'm still stumped. Any help would be greatly appreciated.
Passing the following URL from my browser to the service causes a AddressFilter mismatch fault (below).
http://localhost:9409/PPInfo.svc/ReadResponse?RESULT=0&AUTHCODE=10001&RESPMSG=APROVED&PNREF=12345
produces
<Fault xmlns="http://schemas.microsoft.com/ws/2005/05/envelope/none">
- <Code>
<Value>Sender</Value>
- <Subcode>
<Value xmlns:a="http://schemas.microsoft.com/ws/2005/05/addressing/none">a:DestinationUnreachable</Value>
</Subcode>
</Code>
- <Reason>
<Text xml:lang="en-US">The message with To 'http://localhost:9409/PPInfo.svc/ReadResponse?RESULT=0&AUTHCODE=10001&RESPMSG=APROVED&PNREF=12345' cannot be processed at the receiver, due to an AddressFilter mismatch at the EndpointDispatcher. Check that the sender and receiver's EndpointAddresses agree.</Text>
</Reason>
</Fault>
// web.config
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="ASEEESPrivate.PPInfoBehavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service behaviorConfiguration="ASEEESPrivate.PPInfoBehavior" name="ASEEESPrivate.PPInfo">
<endpoint address="" binding="webHttpBinding" contract="ASEEESPrivate.IPPInfo">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
</services>
</system.serviceModel>
</configuration>
================================
[ServiceContract]
public interface IPPInfo
{
// expecting RESULT = 0 and RESPMSG = APPROVED
[OperationContract]
[WebGet(UriTemplate = "Presponse?RESULT={result}&AUTHCODE={authcode}&RESPMSG={respmsg}&AVSDATA={avsdata}&PNREF={pnref}",
BodyStyle = WebMessageBodyStyle.Bare, RequestFormat = WebMessageFormat.Xml)]
void ReadResponse();
}
=========================================
// write parameters of query string to tlkpOnlineMessage table
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall, AddressFilterMode=AddressFilterMode.Any)]
public class PPInfo : IPPInfo
{
public void ReadResponse()
{
var qString = HttpContext.Current.Request.QueryString;
var ctx =
new MembershipEntities();
var log = new tlkpOnlineMessage();
foreach (string s in qString)
{
log.LoginPageMsg = s;
ctx.AddTotlkpOnlineMessages(log);
}
ctx.SaveChanges();
}
}
Besides the typo in your code, I believe you have two problems that are easily correctable:
1) For a RESTful service, you should define an endpoint behavior and enable the webHttp behavior. You can do this by adding an <endpointBehavior> to your web.config as such:
<behaviors>
<serviceBehaviors>
<behavior name="ASEEESPrivate.PPInfoBehavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="ASEEESPrivate.PPInfoEndpointBehavior">
<webHttp />
</behavior>
</endpointBehaviors>
</behaviors>
And then add this endpoint behavior to your service definition:
<service behaviorConfiguration="ASEEESPrivate.PPInfoBehavior" name="WcfRestService1.PPInfo">
<endpoint address="" binding="webHttpBinding" contract="WcfRestService1.IPPInfo"
behaviorConfiguration="ASEEESPrivate.PPInfoEndpointBehavior">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
2) Secondly, you define a UriTemplate for your service with placeholders (result, authcode, etc.) but you don't define parameters for them in your interface. If you're going to define a UriTemplate for your service definition with placeholders, then you need to have your service define those parameters accordingly. You can do that as such:
[ServiceContract]
public interface IPPInfo
{
// expecting RESULT = 0 and RESPMSG = APPROVED
[OperationContract]
[WebGet(UriTemplate = "ReadResponse?RESULT={result}&AUTHCODE={authcode}&RESPMSG={respmsg}&AVSDATA={avsdata}&PNREF={pnref}",
BodyStyle = WebMessageBodyStyle.Bare, RequestFormat = WebMessageFormat.Xml)]
void ReadResponse(string result, string authcode, string respmsg, string avsdata, string pnref);
}
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall, AddressFilterMode = AddressFilterMode.Any)]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class PPInfo : IPPInfo
{
public void ReadResponse(string result, string authcode, string respmsg, string avsdata, string pnref)
{
...
}
}
By using a UriTemplate, you don't need to extract your querystring parameters out; or, if you want to extract parameters from your querystring, don't define a UriTemplate.
Once I made these two changes, I was able to get the service to run locally on my machine.
I hope this helps!