Testing POST request w/ Parameters to WCF Service - json

I've created a WCF web service which is hosted locally through IIS. I've used the WCF test client to confirm that the service is working properly, and I am now wanting to test through a manual REST call. I'm using RESTClient 3.1 to send the REST calls. I'm able to retrieve results from methods, but my attempts to send JSON in as parameters always results in null parameters. What am I doing wrong? The return body from my request is "FAIL :(" Thanks in advance! I've spent over a day on this problem so far.
Service Contract:
[OperationContract]
[WebInvoke(
Method = "POST",
ResponseFormat = WebMessageFormat.Json,
BodyStyle = WebMessageBodyStyle.Bare)]
public string Route2(Position start)
{
if (start == null)
{
return "FAIL :(";
}
else
{
return "SUCCESS :)";
}
}
** web.config: **
<?xml version="1.0"?>
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0"/>
</system.web>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true">
<add name="UrlRoutingModule" type="System.Web.Routing.UrlRoutingModule, System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
</modules>
<handlers>
<add name="UrlRoutingHandler" preCondition="integratedMode" verb="*" path="UrlRouting.axd"/>
</handlers>
<defaultDocument>
<files>
<add value="help" />
</files>
</defaultDocument>
</system.webServer>
<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>
<services>
<service name="Primordial.GroundGuidance.Service.GroundGuidanceService">
<endpoint address="soap" binding="basicHttpBinding" contract="Primordial.GroundGuidance.Service.GroundGuidanceService" />
<endpoint address="" binding="webHttpBinding" bindingConfiguration=""
name="web" contract="Primordial.GroundGuidance.Service.GroundGuidanceService"
kind="webHttpEndpoint" endpointConfiguration="webEndpointWithHelp" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
</services>
<standardEndpoints>
<webHttpEndpoint>
<standardEndpoint name="webEndpointWithHelp" helpEnabled="true"/>
</webHttpEndpoint>
</standardEndpoints>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
Because I'm using RESTClient the call isn't just a string/file, but for header value pairs I have:
Accept: application/json
contentType: application/json
The body type is set to "application/json; charset=UTF-8"
body:
{
"elevation": 0,
"latitude": 35.31,
"longitude": -116.41
}

After digging at my problem for another day, it ended up being my JSON, not my use of WCF. I needed to specify the method parameter names in my JSON. For my method
[WebInvoke(
Method = "POST",
ResponseFormat = WebMessageFormat.Json,
BodyStyle = WebMessageBodyStyle.WrappedRequest)]
public string Route2(Position start, Position end)
the appropriate JSON was:
{
"start": {
"elevation": 1,
"latitude": 35.3,
"longitude": -116.4
},
"end": {
"elevation": 1,
"latitude": 35.3,
"longitude": -116.4
}
}

Related

WCF stream json request method not found

facing issues when send attach image to wcf server using json request to WCF. error is method not allowed.
Here is Interface
[ServiceContract]
public interface IFileUploadServ
{
[OperationContract(Name = "UploadFile")]
[WebInvoke(Method = "POST", UriTemplate = "/UploadFile", ResponseFormat = WebMessageFormat.Json)]
string UploadFile(Stream stream);
}
Here is implementation
public string UploadFile(Stream stream)
{
// Code will be here to read stream and upload to DB
return "Done";
}
Here is web config
<configuration>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true" />
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Headers" value="Content-Type" />
<add name="Access-Control-Allow-Methods" value="GET, POST" />
</customHeaders>
</httpProtocol>
</system.webServer>
<system.web>
<compilation debug="true" targetFramework="4.5" />
<httpRuntime targetFramework="4.5" />
</system.web>
<system.serviceModel>
<bindings>
<webHttpBinding>
<binding name="MyWcfRestService.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 behaviorConfiguration="MyWcfRestService.FileUploadServBehavior" name="ImageUpload.FileUploadServ">
<endpoint address="" behaviorConfiguration="web" binding="webHttpBinding" bindingConfiguration="MyWcfRestService.WebHttp" contract="ImageUpload.IFileUploadServ">
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://10.100.103.41/DCASTestService/FileUploadServ.svc"/>
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<endpointBehaviors>
<behavior name="web">
<webHttp />
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="MyWcfRestService.FileUploadServBehavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
<standardEndpoints>
<webScriptEndpoint>
<standardEndpoint name="" crossDomainScriptAccessEnabled="true" />
</webScriptEndpoint>
</standardEndpoints>
</system.serviceModel>
</configuration>
Here is json call
json call to wcf service hosted in server
function UploadFile() {
fileData = document.getElementById("fileUpload").files[0];
var data = new FormData();
$.ajax({
url: 'http://10.100.103.41/DCASTestService/FileUploadServ.svc/UploadFile',
type: 'POST',
data : fileData,
cache: false,
dataType: 'json',
processData: false, // Don't process the files
contentType: "application/octet-stream", // Set content type to false as jQuery will tell the server its a query string request
success: function (data) {
alert('successful..' + data.UploadFileResult);
},
error: function (data) {
alert('Some error Occurred!' + data.UploadFileResult);
}
});
}

WCF service Post error on IIS 6

I have developed a REST service that used to run localy on my PC and had no issues!!I have hosted my wcf on a windows server 2008-r2 IIS 7.5, in order to call my service from an IP. I am using the get method with a JSON and all works fine, but when i try the post( with chrome plugin) i get 405 error and 500 error. I checked the MIME-TYPES and added json for IIS. Any solution or suggestiong how to resolve this error would be very useful.
I will post my webconfig and ISERVICE files as well.
My webConfig file is as follows:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.web>
<compilation targetFramework="4.0" />
</system.web>
<system.serviceModel>
<services>
<service name="RestService.RestServiceImpl" behaviorConfiguration="ServiceBehaviour">
<!-- Service Endpoints -->
<!-- Unless fully qualified, address is relative to base address supplied above -->
<endpoint address="" binding="webHttpBinding" contract="RestService.IRestServiceImpl" behaviorConfiguration="Services.webHttpBehavior">
<!--
Upon deployment, the following identity element should be removed or replaced to reflect the
identity under which the deployed service runs. If removed, WCF will infer an appropriate identity
automatically.
-->
</endpoint>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="ServiceBehaviour">
<!-- 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="web">
<webHttp/>
</behavior>
<behavior name="Services.webHttpBehavior">
<webHttp defaultOutgoingResponseFormat="Json" />
</behavior>
</endpointBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
<diagnostics>
<messageLogging logEntireMessage="true" logMalformedMessages="true" logMessagesAtServiceLevel="true" logMessagesAtTransportLevel="true" />
</diagnostics>
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true" />
<!-- <staticContent>
<mimeMap fileExtension=".json" mimeType="application/json"/>
</staticContent>-->
</system.webServer>
<system.diagnostics>
<sources>
<source name="System.ServiceModel" switchValue="Information, ActivityTracing" propagateActivity="true">
<listeners>
<add name="traceListener" type="System.Diagnostics.XmlWriterTraceListener" initializeData="C:\wcflog3.txt" />
</listeners>
</source>
</sources>
</system.diagnostics>
</configuration>
My Service Implementtion is as followes:
[OperationContract]
[WebInvoke(Method = "GET",
ResponseFormat = WebMessageFormat.Xml,
BodyStyle = WebMessageBodyStyle.Wrapped,
UriTemplate = "xml/{str}")]
string XMLData(string str);
[OperationContract]
[WebInvoke(Method = "POST",
ResponseFormat = WebMessageFormat.Json,
BodyStyle = WebMessageBodyStyle.Bare,
RequestFormat = WebMessageFormat.Json,
UriTemplate = "jsoncheckifexists")]
bool CheckIfExists(RestService.RestServiceImpl.UrlObject data);
The GET is working just fine, I try the POST calling the function CheckIfExists:
public bool CheckIfExists(UrlObject urlObject)
{
string link= urlObject.url;
//Standard logon to CRM procedure(Framework)
if abc=true
return true;
else false;
}

WCF Rest POST Method is getting null json string

WCF Rest POST is always getting null string. I have spend more than a week time to explore but no luck so far...
My Service Code:
[ServiceContract]
public interface ISaveSurvey
{
[WebInvoke(Method = "POST",
ResponseFormat = WebMessageFormat.Json,
RequestFormat = WebMessageFormat.Json,
BodyStyle = WebMessageBodyStyle.Wrapped,
UriTemplate = "/SSS")]
bool InsertSiteSurveyInfo(string jsonString);
}
Web Config:
<compilation debug="false" targetFramework="4.0" />
</system.web>
<system.serviceModel>
<services>
<service name="Honeywell.HBS.SiteSurvey.SaveSurvey" behaviorConfiguration="SaveSurvey">
<endpoint address="" binding="webHttpBinding" contract="Honeywell.HBS.SiteSurvey.ISaveSurvey" behaviorConfiguration="wcfRestBehavior"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="SaveSurvey">
<!-- 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="wcfRestBehavior">
<webHttp />
</behavior>
</endpointBehaviors>
</behaviors>
<bindings>
<!-- Customizations for REST service -->
<webHttpBinding>
<binding name="ApiExportBinding" maxReceivedMessageSize="10485760"
maxBufferPoolSize="10485760" maxBufferSize="10485760">
<readerQuotas maxDepth="32" maxStringContentLength="10485760"
maxArrayLength="10485760" maxBytesPerRead="10485760" />
<security mode="None" />
</binding>
</webHttpBinding>
</bindings>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true"/>
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
</system.webServer>
Client Code:
<script type="text/javascript" language="javascript">
function testRest() {
$.ajax({
type: "POST",
dataType: "json",
url: "http://ie22ltjpsd4bs/SSTest/SaveSurvey.svc/SSS",
contentType: "application/json",
data: "{\"siteInformation\":{\"siteName\":\"Malar\",\"siteNumber\":\"123344555\",\"siteContactPerson\":\"test\",\"siteAddress\":\"test\",\"siteCity\":\"test\",\"sitePostalZipCode\":\"test\",\"siteTelephone\":1234576788,\"siteContractNumber\":\"asdfasdf\",\"siteHoneywellBranch\":\"asdfasdf\",\"siteFieldSiteLeader\":\"asdfasdf\",\"siteTeamLead\":\"asdfasdf\",\"siteTechnician\":\"asdfasdf\",\"equipments\":[{\"equipmentID\":\"BRANCH TOOL INVENTORY\",\"equipSiteContactTelephone\":12345678,\"equipDescription\":\"asdfasdf\",\"equipLocation\":\"asdfasdf\",\"equipSupervisionOrFrontEnd\":\"asdfasdf\",\"equipNumberOfStations\":12,\"equipMakeOrTypePC\":\"asdfasdf\",\"equipWindowsVersion\":\"asdfasdf\",\"equipManufacturer\":\"A C MOTOR\",\"equipManufacturerDateOrAge\":\"1979-12-31T18:30:00.000Z\",\"equipProductNameOrVersion\":\"asdfasdf\",\"equipGraphicSoftwareIncl\":\"No\",\"equipExistingSaveBackup\":\"Yes\",\"equipBackupSaveFormat\":\"\",\"equipLocalAccess\":\"asdfasdf\",\"equipPassword\":\"asdfasdfasdf\",\"equipRemoteAccess\":\"Modem\",\"equipAccessInfo\":\"asdfasdf\",\"equipSystemArchitecture\":\"Yes\",\"equipArchivedInAdept\":\"Yes\",\"equipOtherInformation\":\"asdfasdf\",\"controllersInformation\":[{\"controllerName\":\"asdfasdf\",\"controllerQuantity\":\"121\",\"controllerManufacturer\":\"asdfasdf\",\"controllerSoftwareProgram\":\"Yes\",\"controllerProductNameOrVersion\":\"asdfasdf\",\"controllerTypeOfProgram\":\"Interpreted\",\"controllerExistingSaveBackup\":\"Yes\",\"controllerBackUpSaveFormat\":\"\",\"controllerLocalAccess\":\"asdf\",\"controllerPassword\":\"asdf\",\"controllerRemoteAccess\":\"Modem\",\"controllerAccessInfo\":\"asdf\",\"controllerControlDrawings\":\"Yes\",\"controllerOperatingSequence\":\"Yes\",\"controllerOtherInformation\":\"asdfasddf\"}]}]}}",
success: function(result)
{
alert("Sucess");
},
failure: function(result)
{
alert("Failure");
}
});
}
function (result) {
}
</script>
Button Click:
<asp:Button ID="Button1" runat="server" onclick="Button1_Click" OnClientClick="testRest()" Text="Button" />
I attached the w3wp process and try to debug the service and the json string is always getting null. But I used fiddler to intercept the request the json string is getting posted bu the service implementation code always getting null..
That's planned behavior. Your service doesn't know how to map the data you pass.
If you are going to pass your json stuff as a string you should wrap it like this:
data: JSON.stringify({ jsonString: "your_data" })

Endpoint not found WCF

I have WCF library that I hosted , the login function work well, but the second function ReturnCounter
the interface is :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.ServiceModel.Web;
namespace PMAService
{
[ServiceContract]
public interface IPMA
{
[OperationContract]
string Login(string username, string password);
[OperationContract]
List<usp_ReturnEncounter_Result> ReturnEncounter();
}
}
and the code is
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel.Web;
using System.Security.Cryptography;
using System.Web.Security;
namespace PMAService
{
public class PMA : IPMA
{
[WebInvoke(Method = "GET",
ResponseFormat = WebMessageFormat.Json,
UriTemplate = "LogIn/{username}/{password}")]
public string Login(string username, string password)
{
if (Membership.ValidateUser(username, password))
return "true";
else
return "false";
}
// Method to retrieve the Counter
[WebInvoke(Method = "GET",
ResponseFormat = WebMessageFormat.Json,
UriTemplate = "ReturnEncounter")]
public List<usp_ReturnEncounter_Result> ReturnEncounter()
{
using (PMAEntities context = new PMAEntities())
{
return context.usp_ReturnEncounter().ToList();
}
}
}
}
where I connect to Entity framework
the web.config look like
<?xml version="1.0"?>
<configuration>
<appSettings/>
<connectionStrings>
</connectionStrings>
<system.web>
<compilation debug="true" targetFramework="4.0"/>
<roleManager enabled="true" />
<membership>
<providers>
<remove name="AspNetSqlMembershipProvider"/>
<add name="AspNetSqlMembershipProvider"
type="System.Web.Security.SqlMembershipProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
connectionStringName="Login"
enablePasswordRetrieval="false"
enablePasswordReset="true"
requiresQuestionAndAnswer="false"
applicationName="/"
requiresUniqueEmail="false"
passwordFormat="Hashed"
maxInvalidPasswordAttempts="5"
minRequiredPasswordLength="1"
minRequiredNonalphanumericCharacters="0"
passwordAttemptWindow="10"
passwordStrengthRegularExpression="" />
</providers>
</membership>
<authentication mode="Windows"/>
<customErrors mode="On"/>
</system.web>
<system.serviceModel>
<services>
<service name="PMAService.PMA">
<endpoint binding="webHttpBinding" contract="PMAService.IPMA" behaviorConfiguration="web">
</endpoint>
</service>
</services>
<behaviors>
<endpointBehaviors>
<behavior name="web">
<webHttp />
</behavior>
</endpointBehaviors>
</behaviors>
</system.serviceModel>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
</startup>
</configuration>
the login/x/y work well, while ReturnCounter give the error endpoint not found
any idea to fix that please
First of all enable Tracing on your Service and see what is the cause for exception.
Also you would consider increasing ReaderQuotas on your server and client side so that larger data is passed without any problem. Sample shown below:
<system.serviceModel>
<bindings>
<webHttpBinding>
<binding maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647">
<readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647"
maxArrayLength="2147483647" maxBytesPerRead="2147483647"
maxNameTableCharCount="2147483647" />
<security mode="None" />
</binding>
</webHttpBinding>
</bindings>
</system.serviceModel>  
 
Also i see in your code that you are passing the object fetched by entity framework directly. There are situations where the entity framework objects dont get deserialzed and might cause exception. Create a simple POCO and then populate the fetched data and return the POCO.
Why WebInvoke?
For use of a Get operation you need to use WebGet for this Method.
WebInvoke is for just Executing Insert Update Delete uperations.
We use POST, PUT and DELETE method names for them.(Orderly)
When you need to get some data you should do something like that,
[WebGet(UriTemplate = "ReturnEncounter",
RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
As you notice there is a request format this may be XML or JSON enumed on WebMessageFormat.
For post ops. you may use WebRequest object.
Hope helps.

WCF Json GET Service: Check that the sender and receiver's EndpointAddresses agree

I've been working in .NET for a while now, but I'm new to WCF. I'm trying to create my very first WCF service using JSON. I thought I would start really, really simple and then build from there. But I have somehow managed to screw up even the most simple of services. Here's what I've got so far.
Web.Config:
<?xml version="1.0"?>
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0" />
</system.web>
<system.serviceModel>
<services>
<service name="MarathonInfo.MarathonInfoService">
<endpoint address="http://localhost:10298/MarathonInfoService.svc" binding="webHttpBinding" contract="MarathonInfo.IMarathonInfo" />
</service>
</services>
<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>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="false" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
</system.webServer>
</configuration>
Then, in the service file:
namespace MarathonInfo
{
public class MarathonInfoService : IMarathonInfo
{
public String GetData()
{
return "Hello World";
}
}
}
And in the interface:
namespace MarathonInfo
{
[ServiceContract]
public interface IMarathonInfo
{
[OperationContract]
[WebInvoke(Method = "GET", UriTemplate = "/GetData", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
String GetData();
}
}
So, when I go to this url:
http://localhost:10298/MarathonInfoService.svc/GetData
I get this error:
The message with To
'http://localhost:10298/MarathonInfoService.svc/GetData' cannot be
processed at the receiver, due to an AddressFilter mismatch at the
EndpointDispatcher. Check that the sender and receiver's
EndpointAddresses agree.
I am able to execute the service just fine through Visual Studio in debug mode. But in the browser, I only get that error.
What am I doing wrong?
Thanks!
Casey
If you want to create a WCF WebHTTP Endpoint (i.e., one which returns JSON, and uses the [WebGet] / [WebInvoke] attributes), the endpoint needs to have the <webHttp/> behavior associated with it.
<system.serviceModel>
<services>
<service name="MarathonInfo.MarathonInfoService">
<endpoint address="http://localhost:10298/MarathonInfoService.svc"
binding="webHttpBinding"
contract="MarathonInfo.IMarathonInfo"
behaviorConfiguration="Web"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="Web">
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="false" />
</system.serviceModel>