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" })
Related
I need a windows service in which the REST API dumps a bunch of JSON objects into a stream (content-type: application/stream+json).
Example response (not array of objects):
{ id: 1, name: "name 1" }
{ id: 2, name: "name 2" }
{ id: 3, name: "name 3" }
{ id: 4, name: "name 4" }
It is possible doing this in WCF REST? Or maybe I should try something other?
After a few days I found a solution of my case. First I was modify App.config file and add binding configuration to the endpoint that allow streamed response. Next, operation of service contract must have return Stream. Then in implementation of service contract I set outgoing response content type to "application/stream+json", serialize all objects using DataContractJsonSerializer and write to MemoryStream. At the end I was set position of MemoryStream to zero and then return that stream.
Sample code bellow.
App.config:
<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
<services>
<service name="WinService.WcfService">
<endpoint address="" binding="webHttpBinding" bindingConfiguration="webHttpBindingStreamedResponse" contract="WinService.IWcfService" behaviorConfiguration="webHttp" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
</services>
<bindings>
<webHttpBinding>
<binding name="webHttpBindingStreamedResponse" transferMode="StreamedResponse" maxReceivedMessageSize="67108864"/>
</webHttpBinding>
</bindings>
<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="True" />
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="webHttp">
<webHttp />
</behavior>
</endpointBehaviors>
</behaviors>
</system.serviceModel>
ServiceContract:
[ServiceContract]
public interface IWcfService
{
[OperationContract]
[WebGet(UriTemplate = "/stream/{param}", ResponseFormat = WebMessageFormat.Json)]
Stream GetJsonStreamedObjects(string param);
}
Implementation of ServiceContract:
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class WcfService : IWcfService
{
public Stream GetJsonStreamedObjects(string param)
{
var stream = new MemoryStream();
var serializer = new DataContractJsonSerializer(typeof(JsonObjectDataContract));
WebOperationContext.Current.OutgoingResponse.ContentType = "application/stream+json";
foreach (JsonObjectDataContract jsonObjectDataContract in Repository.GetJsonObjectDataContracts(param))
{
serializer.WriteObject(stream, jsonObjectDataContract);
}
stream.Position = 0;
return stream;
}
}
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);
}
});
}
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;
}
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
}
}
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>