WCF REST service does not work with parameter in URI - wcf

I have a WCF REST service (.NET4).
It works fine (browser, ajax call) for calls without parameters but I cannot get it to work with parameters. Neither in the browser nor via an ajax call.
My contract:
[OperationContract]
[WebGet(
ResponseFormat = WebMessageFormat.Json,
UriTemplate = "knowledgefields")]
IEnumerable<cKnowledgeField> GetKnowledgeFields();
[OperationContract]
[WebGet(
BodyStyle = WebMessageBodyStyle.Bare,
ResponseFormat = WebMessageFormat.Json,
RequestFormat = WebMessageFormat.Json,
UriTemplate = "knowledgeitems?id={id}")]
IEnumerable<cKnowledgeItem> GetKnowledgeItemsByField(string id);
My web.config
<configuration>
<appSettings/>
<system.web>
<compilation debug="true" targetFramework="4.0">
<assemblies>
<add assembly="System.Data.Entity, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
</assemblies>
</compilation>
</system.web>
<system.serviceModel>
<standardEndpoints>
<webHttpEndpoint>
<standardEndpoint name="" automaticFormatSelectionEnabled="false" defaultOutgoingResponseFormat="Json"/>
</webHttpEndpoint>
</standardEndpoints>
<services>
<service name="ExpertData.expertREST" behaviorConfiguration="META">
<endpoint address="" bindingConfiguration="webHttpBindingWithJsonP" binding="webHttpBinding" contract="ExpertData.IexpertREST"/>
</service>
</services>
<protocolMapping>
<add scheme="http" binding="webHttpBinding"/>
</protocolMapping>
<behaviors>
<serviceBehaviors>
<behavior name="META">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior>
<webHttp />
</behavior>
</endpointBehaviors>
</behaviors>
<bindings>
<webHttpBinding>
<binding name="webHttpBindingWithJsonP" crossDomainScriptAccessEnabled="true"/>
</webHttpBinding>
</bindings>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="false" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
<directoryBrowse enabled="true"/>
</system.webServer>
<connectionStrings>
<add name="FindAnExpertEntities" connectionString="metadata=res://*/ExpertData.csdl|res://*/ExpertData.ssdl|res://*/ExpertData.msl;provider=System.Data.SqlClient;provider connection string="data source=WIN8ATWORK\SQLEXPRESS;initial catalog=FindAnExpert;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework"" providerName="System.Data.EntityClient"/>
</connectionStrings>
</configuration>
Ajax call:
function getKnowledgeItems(id) {
return $.ajax({
url: "http://localhost:31634/expertREST.svc/knowledgeitems",
dataType: "jsonp"
data: { "id" : id + "" }
}).then( function( data, textStatus, jqXHR ) {
amplify.publish( "knowledgeItemsdata.updated", data );
});
}

Your AJAX call is passing the ID in the message body, BUT you service expects it as as part of the query string. Change javascript to:
return $.ajax({
url: "http://localhost:31634/expertREST.svc/knowledgeitems"
+ "?id=" + id,
dataType: "jsonp"
}).then( function( data, textStatus, jqXHR ) {
amplify.publish( "knowledgeItemsdata.updated", data );
});

Related

How to call WCF Rest service with Basic Auth using Postman?

I have created a WCF service with Basic Authentication following this article https://learn.microsoft.com/en-gb/dotnet/framework/wcf/feature-details/transport-security-with-basic-authentication.
But when I call it using Postman, I get an error (400 Bad Request).
If I use a small application written in C# setting out ClientCredentials, it works well.
Here is my server code:
public class DataService : IDataService
{
public bool GetData()
{
return true;
}
}
[ServiceContract]
public interface IDataService
{
[OperationContract]
[WebInvoke(Method = "GET", UriTemplate = "GetData")]
bool GetData();
}
<?xml version="1.0"?>
<configuration>
<appSettings>
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
</appSettings>
<system.web>
<compilation debug="true" targetFramework="4.6.2" />
<httpRuntime targetFramework="4.6.2"/>
</system.web>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
<protocolMapping>
<add binding="basicHttpsBinding" scheme="https" />
</protocolMapping>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
<bindings>
<wsHttpBinding>
<binding name="UsernameWithTransport">
<security mode="Transport">
<transport clientCredentialType="Basic" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<services>
<service name="BasicAuthenticationTest">
<endpoint
address=""
binding="wsHttpBinding"
bindingConfiguration="UsernameWithTransport"
name="BasicEndpoint"
contract="BasicAuthTest.IDataService"/>
</service>
</services>
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
<directoryBrowse enabled="true"/>
</system.webServer>
</configuration>
I also turned off "SSL certificate verification" and proxy in Postman

There was no channel actively listening at .This is often caused by an incorrect address URI

When I am calling the wcf service from RestClient getting the error:
[EndpointNotFoundException]: There was no channel actively listening at 'http://localhost/Test/TestService.svc/TestMethod'. This is often caused by an incorrect address URI. Ensure that the address to which the message is sent matches an address on which a service is listening.
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0"/>
</system.web>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="mexBehaviour">
<serviceMetadata httpGetEnabled="true"/>
<useRequestHeadersForMetadataAddress>
<defaultPorts>
<add scheme="http" port="80" />
</defaultPorts>
</useRequestHeadersForMetadataAddress>
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service name="TestService.TestService" behaviorConfiguration="mexBehaviour">
<endpoint address="TestService" binding="basicHttpBinding" contract="TestService.ITestService"/>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange">
</endpoint>
<host>
<baseAddresses>
<add baseAddress="http://localhost/Test/"/>
</baseAddresses>
</host>
</service>
</services>
</system.serviceModel>
</configuration>
Have searched many similar issue but not resolving, Kindly help..
Here is the service code:
namespace TestService
{
[ServiceContract]
public interface ITestService
{
[OperationContract, WebInvoke(Method = "POST", ResponseFormat = WebMessageFormat.Json)]
string TestMethod();
}
}
namespace TestService
{
public class TestService: ITestService
{
public string TestMethod()
{
return "Hello";
}
}
}
add UriTemplate = "Test/"
namespace TestService
{
[ServiceContract]
public interface ITestService
{
[OperationContract,WebInvoke(Method = "POST",ResponseFormat = WebMessageFormat.Json,UriTemplate = "Test/")]
string TestMethod();
}
}
config:
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0"/>
</system.web>
<system.serviceModel>
<bindings>
<webHttpBinding>
<binding name="webHttp"
maxReceivedMessageSize="20000000" >
<security mode="None">
<transport clientCredentialType = "None"/>
</security>
</binding>
</webHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="mexBehaviour">
<serviceMetadata httpGetEnabled="true"/>
<useRequestHeadersForMetadataAddress>
<defaultPorts>
<add scheme="http" port="80" />
</defaultPorts>
</useRequestHeadersForMetadataAddress>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="web">
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
<services>
<service name="TestService.TestService" behaviorConfiguration="mexBehaviour">
<endpoint address="" binding="webHttpBinding" contract="TestService.ITestService" bindingConfiguration="webHttp" behaviorConfiguration="web"/>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange">
</endpoint>
</service>
</services>
</system.serviceModel>
</configuration>

How to Receive Multipart Form Data on WCF Service. I have uploaded it using the phone gap file transfer plugin upload function

How can I receive multipart form data in a WCF Service? I have uploaded it using the phone gap file transfer plugin upload function.
Below are the two functions that I'm trying to call:
///<summary>
///Method for file upload
///</summary>
[OperationContract]
[WebInvoke(
Method = "POST",
BodyStyle = WebMessageBodyStyle.Bare,
UriTemplate = "Upload")]
string Upload(Stream data);
[OperationContract]
[WebInvoke(BodyStyle = WebMessageBodyStyle.Wrapped, Method = "POST", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, UriTemplate = "UploadImage")]
string UploadImage();
// TODO: Add your service operations here
I successfully hit the UploadImage function but I don't know how to read a file from the uploaded data.
When I try
HttpPostedFile file = HttpContext.Current.Request.Files["recFile"];
I get the error:
HttpContext.Current.Request.Files 'HttpContext.Current.Request.Files' threw an exception of type 'System.Web.HttpException' System.Web.HttpFileCollection {System.Web.HttpException}
base {"This method or property is not supported after HttpRequest.GetBufferlessInputStream has been invoked."}
This is my web.config file:
<?xml version="1.0"?>
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.5" />
<customErrors mode="RemoteOnly"/>
<caching>
<outputCacheSettings>
<outputCacheProfiles>
<add name="CacheFor10Seconds" duration="10"
varyByParam="none" />
</outputCacheProfiles>
</outputCacheSettings>
</caching>
<httpRuntime maxRequestLength="2000000000"/>
</system.web>
<appSettings>
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="false" />
</appSettings>
<system.serviceModel>
<bindings>
<webHttpBinding>
<binding name="webHttpBindingWithJsonP"
crossDomainScriptAccessEnabled="true" maxBufferSize="2000000000"
maxReceivedMessageSize="2000000000"
transferMode="Streamed" />
</webHttpBinding>
</bindings>
<behaviors>
<endpointBehaviors>
<behavior name="webHttpBehavior">
<webHttp helpEnabled="true"/>
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true"
multipleSiteBindingsEnabled="true" />
<services>
<service name="Service.Service1">
<endpoint name="mexHttpBinding"
address="mex"
binding="mexHttpBinding"
contract="IMetadataExchange"
/>
<endpoint address="" behaviorConfiguration="webHttpBehavior"
binding="webHttpBinding"
bindingConfiguration="webHttpBindingWithJsonP"
contract="Service.IService1" />
</service>
</services>
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Headers" value="Content-Type" />
</customHeaders>
</httpProtocol>
</system.webServer>
</configuration>
I got the problem it with the Wcf version targetFramework="4.5" issue ,
you have to add below code in web config than the issue get resolve:
<appSettings>
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="false" />
<add key="wcf:serviceHostingEnvironment:useClassicReadEntityBodyMode" value="true" />
</appSettings>
my all the other web Config that i post already here is working fine below is the updated web config setting
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.5" />
<customErrors mode="RemoteOnly"/>
<caching>
<outputCacheSettings>
<outputCacheProfiles>
<add name="CacheFor10Seconds" duration="10"
varyByParam="none" />
</outputCacheProfiles>
</outputCacheSettings>
</caching>
<httpRuntime maxRequestLength="2000000000"/>
</system.web>
<appSettings>
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="false" />
<add key="wcf:serviceHostingEnvironment:useClassicReadEntityBodyMode" value="true" />
</appSettings>
<system.serviceModel>
<bindings>
<webHttpBinding>
<binding name="webHttpBindingWithJsonP"
crossDomainScriptAccessEnabled="true" maxBufferSize="2000000000"
maxReceivedMessageSize="2000000000"
transferMode="Streamed" />
</webHttpBinding>
</bindings>
<behaviors>
<endpointBehaviors>
<behavior name="webHttpBehavior">
<webHttp helpEnabled="true"/>
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true"
multipleSiteBindingsEnabled="true" />
<services>
<service name="Service.Service1">
<endpoint name="mexHttpBinding"
address="mex"
binding="mexHttpBinding"
contract="IMetadataExchange"
/>
<endpoint address="" behaviorConfiguration="webHttpBehavior"
binding="webHttpBinding"
bindingConfiguration="webHttpBindingWithJsonP"
contract="Service.IService1" />
</service>
</services>
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Headers" value="Content-Type" />
</customHeaders>
</httpProtocol>
</system.webServer>
</configuration>
This is my Service and IService Code:
[OperationContract]
[WebInvoke(BodyStyle = WebMessageBodyStyle.Wrapped, Method = "POST", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, UriTemplate = "UploadImage")]
string UploadImage();
#region
///<summary>
///Metohd to upload image.
///</summary>
public string UploadImage()
{
string JsonString = string.Empty;
JsonString = AppDomain.CurrentDomain.BaseDirectory;
try {
HttpPostedFile file = HttpContext.Current.Request.Files[0];
;
if (file == null)
{
RC.ErrorLog.LogFileWrite("<Exception>File is null</Exception>" + JsonString);
return JsonString;
}
string targetFilePath = AppDomain.CurrentDomain.BaseDirectory + #"Images\Upload" + Guid.NewGuid() + file.FileName.ToString();
file.SaveAs(targetFilePath);
return file.FileName.ToString();
}
catch(Exception e)
{
string errorMessage = RC.ErrorLog.CreateErrorMessage(e);
RC.ErrorLog.LogFileWrite(errorMessage+JsonString);
return JsonString;
}
}
#endregion
And below is my JqueryMobile code for PhoneGap
// A button will call this function
//
function captureImage() {
// Launch device camera application,
// allowing user to capture up to 2 images
debugger;
navigator.device.capture.captureImage(captureSuccess, captureError, { limit: 2 });
}
function captureSuccess(mediaFiles) {
var i, len;
for (i = 0, len = mediaFiles.length; i < len; i += 1) {
uploadFile(mediaFiles[i]);
}
}
// Called if something bad happens.
//
function captureError(error) {
var msg = 'An error occurred during capture: ' + error.code;
navigator.notification.alert(msg, null, 'Uh oh!');
}
function uploadFile(mediaFile) {
var ft = new FileTransfer();
path = mediaFile.fullPath;
name = mediaFile.name;
debugger;
// below varible contain the Server url name that i created by joining defenrent 3 var of //my application
var objUrl = _ServicesUrl._SecondServicePath + _ServicePage._BaseServicePage + _WcfFunctionUrl._ImageUpload;
alert("uploadImage");
ft.upload(path,
objUrl,
function (result) {
alert('Upload success: ' + result.responseCode);
alert(result.bytesSent + ' bytes sent');
debugger;
var abc = JSON.parse(result.Upload);
alert(abc);
},
function (error) {
alert('Error uploading file ' + path + ': ' + error.code);
},
{ fileName: name });
}
Hope the answer will help the community.

Cross Domain jQuery AJAX request to WCF - 405 Method not allowed

I am building simple WCF web service for my mobile web app.
I am stack at the point of making the $.ajax request to WCF which comes back with 405 - Method not allow, even though when I do http://http://localhost:35798/RestServiceImpl.svc/json/23 I can see result of the ReturnJSONData() in the browser.
I went through 100's of different post, but none of the answer fixed my problem.
AJAX Request
$.ajax({
type: "GET",
url: "http://localhost:35798/RestServiceImpl.svc/json/34",
contentType: "application/json; charset=utf-8",
success: function(data) {
console.log(data);
},
});
IRestServiceImpl.cs
namespace RestService{
[ServiceContract]
public interface IRestServiceImpl
{
[OperationContract]
[WebInvoke(
Method = "GET",
ResponseFormat = WebMessageFormat.Json,
BodyStyle = WebMessageBodyStyle.Wrapped,
UriTemplate = "json/{id}"
)]
string ReturnJSONData(string id);
}
}
RestServiceImpl.svs.cs
namespace RestService {
public class RestServiceImpl : IRestServiceImpl {
public string ReturnJSONData(string id) {
return "You requested product " + id;
}
}
}
WebConfig
<?xml version="1.0"?>
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0" />
</system.web>
<system.serviceModel>
<services>
<service name="RestService.RestServiceImpl" behaviorConfiguration="ServiceBehaviour">
<endpoint address ="" binding="webHttpBinding" contract="RestService.IRestServiceImpl" behaviorConfiguration="web">
</endpoint>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="ServiceBehaviour">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="web">
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
<standardEndpoints>
<webHttpEndpoint>
<standardEndpoint name=""
helpEnabled="true"
automaticFormatSelectionEnabled="true"
defaultOutgoingResponseFormat ="Json"
crossDomainScriptAccessEnabled="true"/>
</webHttpEndpoint>
</standardEndpoints>
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
</system.webServer>
</configuration>
Any suggestion much appreciated.

Got 404 when consume WCF in REST mode

I used this url in browser, and I expect to see an XML, I only got 404 not found error. Can you help please?
--http://SomeIP:65001/WCFPilot/Service1/REST/GetData
web.config
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0" />
<authentication mode="Windows" />
</system.web>
<system.serviceModel>
<services>
<service name="WCFPilot.Service1">
<endpoint address="REST" binding="webHttpBinding" contract="WCFPilot.IService1" behaviorConfiguration="REST">
</endpoint>
</service>
</services>
<behaviors>
<endpointBehaviors>
<behavior name="REST">
<webHttp faultExceptionEnabled="true" helpEnabled="true" />
</behavior>
</endpointBehaviors>
<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="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true" />
</system.webServer>
</configuration>
Service Contract
[ServiceContract]
public interface IService1
{
[OperationContract]
[WebGet(ResponseFormat = WebMessageFormat.Xml, BodyStyle = WebMessageBodyStyle.Wrapped, UriTemplate = "GetData")]
string GetData();
}
Thanks
The URL for the service should be
http://SomeIP:65001/Service1.svc/REST/GetData