Consume WCF service by Javascript - c#

I created a WCF service, that is supposed to be consumed by Javascript(Json) on client side. Websites are generated by ASP.NET MVC. I got everything running on localhost IIS-Express.
Problem is, when I call this WCF service from Javascript, it throws and undefined error.
One of many thoughts, why this error occurs is, that WCF web.config is not set correctly and doesn't allow cross site scripting.
Here is web.config file
<?xml version="1.0"?>
<configuration>
<system.serviceModel>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
<services>
<service behaviorConfiguration="Default"
name="Wcf_Categories.Categories">
<endpoint address=""
behaviorConfiguration="webBehavior"
binding="webHttpBinding"
contract="Wcf_Categories.ICategories" />
<endpoint address="sc"
behaviorConfiguration="script"
binding="webHttpBinding"
bindingConfiguration="crossDomain"
contract="Wcf_Categories.ICategories"/>
<endpoint contract="IMetadataExchange" binding="mexHttpBinding"
address="mex" />
</service>
</services>
<bindings>
<webHttpBinding>
<binding name="crossDomain" crossDomainScriptAccessEnabled="true" />
</webHttpBinding>
</bindings>
<behaviors>
<endpointBehaviors>
<behavior name="webBehavior">
<webHttp helpEnabled="true" />
</behavior>
<behavior name="script">
<enableWebScript/>
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="Default">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
<behavior name="">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
</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>
<system.web>
<compilation debug="true"/>
</system.web>
</configuration>
If I call service directly from browser for example localhost:1813/Categories.svc/sc/GetData?name=undefined
it returns suggested data and behaves normally (sites running at localhost/TestSites/Products# )
Here is script for wcf service call
function GetCategories(categoryName) {
$.ajax({
type: "GET",
async: "false",
url: "localhost:1813/Categories.svc/sc/GetData",
contentType: "application/json; charset=utf-8",
dataType: "json",
data : 'name='+categoryName,
processData: true,
success: function (result) {
ServiceSucceeded(result);
},
error: ServiceFailed
});
}
function ServiceSucceeded(result) {
var resultObject;
if (DataType == "json") {
resultObject = result.GetUserResult;
for (i = 0; i < resultObject.length; i++) {
alert(resultObject[i]);
}
}
}
function ServiceFailed(xhr) {
alert(xhr.responseText);<---------------------- Alert output is "undefined". Exception details = [Exception... "<no message>" nsresult: "0x805e0006 (<unknown>)" location: "JS frame :: http://localhost/TestSites/content/js/jquery-1.10.2.min.js :: .send :: line 6" data: no] ------->
if (xhr.responseText) {
var err = xhr.responseText;
if (err)
error(err);
else
error({ Message: "Unknown server error." });
}
return;
}

Related

Web service call through url

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>

WCF REST Endpoint

I am developing a WCF and I want it to be called by both ways SOAP/REST.
Now I am able to get response by SOAP but unable to call the same WCF by JSON request.
IService1.cs
[OperationContract]
[FaultContract(typeof(CustomException))]
[WebInvoke(Method = "POST", UriTemplate = "/Validateuser",
RequestFormat = WebMessageFormat.Xml | WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Xml | WebMessageFormat.Json)]
ResponsetoCustomer Validateuser(ValidateCustomerInput validate);
Web.config
<system.serviceModel>
<services>
<service name="TractorMitraIntegration.IService1" behaviorConfiguration="ServBehave">
<!--Endpoint for SOAP-->
<endpoint
address="soapService"
binding="basicHttpBinding"
contract="TractorMitraIntegration.IService1"/>
<!--Endpoint for REST-->
<endpoint
address="XMLService"
binding="webHttpBinding"
behaviorConfiguration="restPoxBehavior"
contract="TractorMitraIntegration.IService1"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="ServBehave">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
<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 for the REST endpoint for Help enability-->
<behavior name="restPoxBehavior">
<webHttp helpEnabled="true"/>
</behavior>
</endpointBehaviors>
</behaviors>
<protocolMapping>
<add binding="basicHttpsBinding" scheme="https"/>
</protocolMapping>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true"/>
Below error I am facing,
Cannot process the message because the content type 'application/json' was not the expected type 'text/xml; charset=utf-8'
Please help!
You probably need defaultOutgoingResponseFormat="Json":
<behavior name="restPoxBehavior">
<webHttp helpEnabled="true" defaultOutgoingResponseFormat="Json" />
</behavior>
You cannot support both soap and rest for the same endpoint.
See this REST / SOAP endpoints for a WCF service for how to.

WCF POST method get error 400 Bad Request

I am using WCF POST method, once i added parameter POST to the service its return error 400 Bad Request, if i left the parameter empty it can access to my service.
This is my Interface:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using System.ServiceModel.Web;
using System.IO;
namespace SampleArticle
{
// NOTE: You can use the "Rename" command on the "Refactor" menu to change the interface name "IRestService" in both code and config file together.
[ServiceContract(Namespace="IRestService/JSONData")]
public interface IRestService
{
[OperationContract]
[WebInvoke(Method = "POST", ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Wrapped,UriTemplate = "authorize")]
Stream authorize(Stream streamdata);
}
}
This is my Web.config
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appSettings>
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
</appSettings>
<system.web>
<compilation debug="true" targetFramework="4.0" />
</system.web>
<system.serviceModel>
<services>
<service name="SampleArticle.RestService" behaviorConfiguration="serviceBehavior">
<endpoint address="" binding="webHttpBinding" contract="SampleArticle.IRestService" behaviorConfiguration="web"></endpoint>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="serviceBehavior">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="web">
<webHttp />
</behavior>
</endpointBehaviors>
</behaviors>
<protocolMapping>
<add binding="basicHttpsBinding" scheme="https" />
</protocolMapping>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true" />
<directoryBrowse enabled="true" />
</system.webServer>
</configuration>
Im using Msxml2.ServerXMLHTTP to POST
Dim objXmlHttpMain , URL
URL="http://localhost/SampleArticle/RestService.svc/authorize"
strJSONToSend = "{""acctId"": ""Test10001"","
strJSONToSend = strJSONToSend & """language"": 200,"
strJSONToSend = strJSONToSend & """Code"": ""Test"","
strJSONToSend = strJSONToSend & """token"": ""abcd123412341234"","
strJSONToSend = strJSONToSend & """serialNo"": ""20161020160455982841""}"
// if i set the parameter to empty i can access to the service
'strJSONToSend = ""
Set objXmlHttpMain = CreateObject("Msxml2.ServerXMLHTTP")
'on error resume next
objXmlHttpMain.open "POST",URL, False
// if i change the "application/json" to "application/x-www-form-urlencoded" it works
'objXmlHttpMain.setRequestHeader "Content-Type", "application/json"
objXmlHttpMain.setRequestHeader "Content-Type", "application/x-www-form-urlencoded"
objXmlHttpMain.send strJSONToSend
//check for output
S = objXmlHttpMain.responseText
response.write S
set objJSONDoc = nothing
set objResult = nothing
Server log msg
Incoming message for operation 'authorize' (contract 'IRestService' with namespace 'IRestService/JSONData') contains an unrecognized http body format value 'Json'. The expected body format value is 'Raw'. This can be because a WebContentTypeMapper has not been configured on the binding. See the documentation of WebContentTypeMapper for more details.
if i change the Content-Type "application/json" to "application/x-www-form-urlencoded"
it works , but i need the data in JSON format.
Is there any setting i am missing with ? Please advice.
I have solved my question my adding the custom WebContentTypeMapper.
Here are my sample coding :
Create new class to allow receive the data as RAW type
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.ServiceModel.Channels;
namespace SampleArticle
{
public class MyWebContentTypeMapper : WebContentTypeMapper
{
public override WebContentFormat GetMessageFormatForContentType(string contentType)
{
return WebContentFormat.Raw;
}
}
}
Web.Config add custom binding to the service
<system.serviceModel>
<services>
<service name="SampleArticle.RestService" behaviorConfiguration="serviceBehavior">
<endpoint address="" binding="customBinding" bindingConfiguration="RawReceiveCapable" contract="SampleArticle.IRestService" behaviorConfiguration="web"></endpoint>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="serviceBehavior">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="false"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
<behavior name="">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="false"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="web">
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
<bindings>
<customBinding>
<binding name="RawReceiveCapable">
<webMessageEncoding webContentTypeMapperType="SampleArticle.MyWebContentTypeMapper, SampleArticle, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/>
<httpTransport manualAddressing="true" maxReceivedMessageSize="524288000" transferMode="Streamed"/>
</binding>
</customBinding>
</bindings>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true"/>
</system.serviceModel>
This Solved my issue , hope its help other too. Thank for helping

WCF for AJAX - "ordinary" web services: Where's the "d"?

I am trying to catalog for my own education the multiple ways services are used in an asp.net application.
When using a standard (i.e. non-ajax) WCF service, if you use an endpoint behavior with "webHttp", a json result is not wrapped with "d". If you use an endpoint behavior with "enableWebScript", you get the expected "d" wrapper.
Is this a feature of .net 4.5 now, or why is it that you don't get the "d" wrapper with webHttp?
My understanding now is that it is the underlying MS-AJAX infrastructure that implements the "d" wrapper, and if you use WCF without the AJAX infrastructure (e.g. if setting up a RESTful service), you avoid this.
I don't have any real complex implementation - I am just trying to capture the nuances of the different ways of implementing services - but just in case, here is the code I used to discover this behavior with "d".
Here is the exposed method:
[ServiceContract]
public interface IServicesDemo_WCF
{
[OperationContract]
[WebInvoke(Method = "GET", ResponseFormat = WebMessageFormat.Json)]
string ReturnWcfMessage();
}
Here is the config:
<system.serviceModel>
<behaviors>
<endpointBehaviors>
<behavior name="WebService.AJAX_WCFAspNetAjaxBehavior">
<enableWebScript />
</behavior>
<behavior name="WebService.WCFBehavior">
<webHttp />
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
<behavior name="WCFServiceBehavior">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true"
multipleSiteBindingsEnabled="true" />
<services>
<service name="WebService.ServicesDemo_AJAX_WCF">
<endpoint address="" behaviorConfiguration="WebService.AJAX_WCFAspNetAjaxBehavior"
binding="webHttpBinding" contract="WebService.ServicesDemo_AJAX_WCF" />
</service>
<service name="WebService.ServicesDemo_WCF" behaviorConfiguration="WCFServiceBehavior">
<endpoint address="" behaviorConfiguration="WebService.WCFBehavior"
binding="webHttpBinding" contract="WebService.IServicesDemo_WCF" />
</service>
</services>
Here is the call from client:
$.ajax({
type: "Get",
data: data,
contentType: "application/json; charset=utf-8",
url: "ServicesDemo_WCF.svc/ReturnWcfMessage",
success: function (data) {
$('#wcf_content').html(data);
},
error: function (msg) {
alert(msg);
}
});

WCF Json Rest service not hitting the Methods

I am writing a WCF service, (json REST) and I have it working fine when using the wcftestclient.exe
When I run that test tool it triggers my break points while debugging and everything works as expected.
but, when using a browser to navigate to the the service and method, no break point is triggered. it seems as though the request isnt even getting to the code.
I receieve no errors on when navigating with web browser to the service, it just doesn't get any data, or trigger the break points.
Apologies if this is a duplicate, I have read and tried many many different configurations found in answers to similar questions, but nothing seems to work.
Many thanks for any help, I've posted my code below.
Martyn
I have setup:
ServiceContract
[OperationContract]
[WebGet(BodyStyle = WebMessageBodyStyle.Bare, ResponseFormat = WebMessageFormat.Json)]
List<Country> GetAllCountries();
The Service CLass:
public List<Country> GetAllCountries()
{
ControlServiceRepository rep = new ControlServiceRepository();
return rep.GetAllCountries().ToList() ;
}
and my web config
<system.web>
<compilation debug="true" targetFramework="4.0" />
</system.web>
<system.serviceModel>
<services>
<service name="OmniData" behaviorConfiguration="ServiceConfig">
<!-- Service Endpoints -->
<host>
<baseAddresses>
<add baseAddress="http://localhost:55641/"/>
</baseAddresses>
</host>
<endpoint address="" binding="webHttpBinding" contract="ControlService.IOmniData" behaviorConfiguration="rest" />
</service>
</services>
<behaviors>
<endpointBehaviors>
<behavior name="rest">
<webHttp helpEnabled="true"/>
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="ServiceConfig">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
<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>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
<standardEndpoints>
<webHttpEndpoint>
<standardEndpoint name="" helpEnabled="true" automaticFormatSelectionEnabled="false" defaultOutgoingResponseFormat="Json"/>
</webHttpEndpoint>
</standardEndpoints>
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
</system.webServer>
I think there are some things missing in your contract
[OperationContract]
[WebInvoke(Method = "GET", UriTemplate = "/GetAllCountries", RequestFormat = WebMessageFormat.Json,ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.WrappedRequest)]
List<Country> GetAllCountries();
Try this.Let me know if it helps.
I got this working in the end by deleting all the end points in the config and using
RouteTable.Routes.Add(new ServiceRoute("", new WebServiceHostFactory(), typeof(OmniData)));
if anyone else has issues, this is even easier than setting up end points because you can just specify the type of responses and end points within the classes themselves.
so:
Add a global.asax if one does exist and include this:
protected void Application_Start(object sender, EventArgs e)
{
RouteTable.Routes.Add(new ServiceRoute("", new WebServiceHostFactory(), typeof(OmniData)));
}
decorate your Service class with
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
here is mine:
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class OmniData : IOmniData
{
public Country[] GetAllCountries()
{
ControlServiceRepository rep = new ControlServiceRepository();
return rep.GetAllCountries().ToArray() ;
}
}
then the interface you setup your endpoing and types using WebGet or WebInvoke
public interface IOmniData
{
[OperationContract]
[WebGet(UriTemplate = "OmniData/GetAllCountries", ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Bare)]
Country[] GetAllCountries();
}
the UriTemplate is the end point, so to access the method you would use: http://MyService.com/OmniData/GetAllCountries
and finally, web config
<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true"/>
<standardEndpoints>
<webHttpEndpoint>
<standardEndpoint name="" helpEnabled="true" automaticFormatSelectionEnabled="false"/>
</webHttpEndpoint>
</standardEndpoints>
<services>
<service name="OmniData">
<!-- Service Endpoints -->
<host>
<baseAddresses>
<add baseAddress="http://localhost:55641"/>
</baseAddresses>
</host>
<endpoint address="" binding="webHttpBinding" contract="ControlService.IOmniData" behaviorConfiguration="rest" />
</service>
</services>
<behaviors>
<endpointBehaviors>
<behavior name="rest">
<webHttp />
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="Default">
<serviceMetadata httpGetEnabled="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
Alot of help from here
but, importantly for what I wanted, json results, you need to make sure:
automaticFormatSelectionEnabled="false" is in there so it will use the response format specified in the interface. Otherwise you end up with XML instead.
hopefully this helps someone else
And thanks again for fiddler!
Martyn

Categories

Resources