I am creating a simple WCF Restful service. Currently when I browse to: localhost/AzamSharpService.svc it shows me the web services default page where I can examine WSDL.
I want to browse to localhost/AzamSharpService.svc/LatestArticles and get the json from the GetLatestArticles method. Currently, when the browse to the /LatestArticles url it says page not found.
The implementation is shown below:
[ServiceContract]
public interface IAzamSharpService
{
[OperationContract]
[WebGet(BodyStyle = WebMessageBodyStyle.Bare, RequestFormat =WebMessageFormat.Json,ResponseFormat = WebMessageFormat.Json, UriTemplate = "/LatestArticles")]
List<ArticleContract> GetArticles();
}
public class AzamSharpService : IAzamSharpService
{
public List<ArticleContract> GetArticles()
{
var articles = new List<ArticleContract>()
{
new ArticleContract() {Title = "iOS"},
new ArticleContract() { Title="Android"},
new ArticleContract() { Title = "Windows 7"}
};
return articles;
}
}
The configuration is shown below:
<system.serviceModel>
<services>
<service name="AzamSharpNewLook.AzamSharpService">
<endpoint address="AzamSharpService.svc"
binding="webHttpBinding"
contract="AzamSharpNewLook.IAzamSharpService"
behaviorConfiguration="webby"/>
</service>
</services>
<behaviors>
<endpointBehaviors>
<behavior name="webby">
<webHttp/>
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="false" />
</system.serviceModel>
A couple of things to try... set endpoint address to empty string...in the webHttp node try enabling help... and you should be able to navigate to localhost/AzamSharpService.svc/help and get more info. Lastly I would use fiddler and construct a get request to the appropriate address, then just check the response and you should have what you need. Hope this helps...
Related
I have a very simple WCF Service Project in VS2017. But I keep getting error 400 when I try to visit the endpoints. I have read the other questions posted here about the same issue and I have tried them with no luck so far.
My Service Contract:
[ServiceContract]
public interface IService
{
[OperationContract]
[WebInvoke(Method = "GET",
BodyStyle = WebMessageBodyStyle.Wrapped,
RequestFormat = WebMessageFormat.Json,
ResponseFormat = WebMessageFormat.Json,
UriTemplate = "/GetData/{value}")]
string GetData(string value);
}
My Service:
public class Service : IService
{
public string GetData(string value)
{
return string.Format("You entered: {0}", value);
}
}
My Web.Config:
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="myBehavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
<behavior name="">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service behaviorConfiguration="myBehavior" name="WCGFService1.Service">
<endpoint address="" contract="WCGFService1.IService" binding="webHttpBinding">
</endpoint>
</service>
</services>
When I visit http://localhost:61648/Service.svc/GetData/12, I get HTTP 400 Bad Request. I've tried with browser and POSTman. What am I doing wrong?
I am using VS2017. My IService.cs and Service.cs are inside the App_Code folder whereas the
Service.svc is in the root folder. Also, when I try to add the name & contract in web.config, VS2013 suggests me the namespace and the interface/class name, whereas, VS2017 is not suggesting me anything so I have to manually type it.
Also, in VS2013, the Interface and Class were located in the root folder instead of the App_Code folder. The project is a WCF Application in VS2017. My .NET Version is 4.5.2.
Fixed it, had a few problems in the web.config file:
<system.serviceModel>
<behaviors>
<!-- Fix 1: Added a endpointBehavoir with webHttp -->
<endpointBehaviors>
<behavior name="web">
<webHttp />
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="myBehavior">
<serviceMetadata httpGetEnabled="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<!-- Fix 2: Instead of using the full name (WCGFService1.Service), used just the class name (Service) -->
<service behaviorConfiguration="myBehavior" name="Service">
<!-- Fix 3: Same thing here, used just the IService instead of full name, also, used the aforementioned endpointBehavoir -->
<endpoint address="" contract="IService" binding="webHttpBinding" behaviorConfiguration="web">
</endpoint>
</service>
</services>
<protocolMapping>
<add binding="basicHttpsBinding" scheme="https" />
</protocolMapping>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
</system.serviceModel>
That did it for me, for whatever reason, in VS2013, it would not work if you don't provide the full name (namespace and class/interface name) but in VS2017, it works only if you provide just the class/interface name.
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 have this service that was working great until I changed the namespace of the service. Also changed the default namespace in the project. I was getting some errors something about not publishing metadata, so I undid my changes, and not nothing works. I even created a new service to test getting this going again, and not I am getting an http 400 when I try to test my rest service. It's been a long week, and I am fully pulling my hair out. Can anyone see what I am doing wrong here?
Update: The http 400 is gone, this is the error I am seeing:Error: Cannot obtain Metadata from http://localhost:1585/ProdSvc.svc If this is a Windows (R) Communication Foundation service to which you have access, please check that you have enabled metadata publishing at the specified address. For help enabling metadata publishing, please refer to the MSDN documentation at http://go.microsoft.com/fwlink/?LinkId=65455
[OperationContract]
void DoWork();
[OperationContract]
[WebInvoke(Method = "GET",
ResponseFormat = WebMessageFormat.Xml,
BodyStyle = WebMessageBodyStyle.Bare,
UriTemplate = "GetProductName/")]
string GetProductName();
public string GetProductName()
{
return "It worked!!!";
}
<system.serviceModel>
<services>
<service name="TSServices.ProdSvc" behaviorConfiguration="serviceBehavior">
<endpoint address=""
binding="webHttpBinding"
contract="TSServices.ProdSvc"
behaviorConfiguration="web"></endpoint>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="serviceBehavior">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="web">
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
Supertopi's answer was correct. Adding the config sections did the trick.
I created a WCF project and i'm using the WCF Test Client, I got the returned message. However, when I used the browser to the endpoint address, I received Error 404. My code is shown below:
[WebInvoke(Method = "GET", ResponseFormat = WebMessageFormat.Json, UriTemplate = "UpdateTbl/{tblName}")]
public string UpdateTbl(string tblName)
{ ... }
The related code in the config file is below:
<system.serviceModel>
<services>
<service name="WcfJsonRestService.Service1" >
<endpoint address="http://thehost:47423/Service1" binding="webHttpBinding" contract="WcfJsonRestService.IService1" >
</endpoint>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="webHttp">
<webHttp helpEnabled="true" automaticFormatSelectionEnabled="true"/>
</behavior>
</endpointBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
Please help if you can share your experience. Thanks.
You can't configure service activation by providing a URL for the endpoint. The syntax you're using for the endpoint element is appropriate for a client configuration file, not a service. You must either use the URL of an SVC file for activation, or use a more sophisticated activation scheme, as discussed here and here.
I'm working on a mobile app using PhoneGap, and one of the features involves uploading an image to a web service for processing. I've written a WCF service that's hosted in IIS to accept the image, with a contract that looks like the following:
[ServiceContract]
public interface IImages
{
[OperationContract(Name="UploadImage")]
[WebInvoke(UriTemplate = "?file_key={fileKey}", Method = "POST", BodyStyle = WebMessageBodyStyle.Bare)]
ImageResource UploadImage(string fileKey, Stream imageStream);
}
The configuration section in my web.config looks like:
<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true">
<serviceActivations>
<add service="Services.Images" relativeAddress="images.svc" />
</serviceActivations>
</serviceHostingEnvironment>
<services>
<service behaviorConfiguration="DefaultServiceBehavior" name="Services.Images">
<endpoint behaviorConfiguration="DefaultEndpointBehavior" binding="webHttpBinding" bindingConfiguration="PublicStreamBinding" contract="Services.Contracts.IImages" />
</service>
</services>
<bindings>
<webHttpBinding>
<binding name="PublicStreamBinding"
maxReceivedMessageSize="2000000000" transferMode="Streamed">
<security mode="None" />
</binding>
</webHttpBinding>
</bindings>
<behaviors>
<endpointBehaviors>
<behavior name="DefaultEndpointBehavior">
<webHttp helpEnabled="true" />
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="DefaultServiceBehavior">
<serviceMetadata httpGetEnabled="false" />
<serviceDebug includeExceptionDetailInFaults="true" />
<serviceThrottling maxConcurrentCalls="30" maxConcurrentInstances="30" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
When I attempt to upload a file to the endpoint, using PhoneGap's FileTransfer class, the response returned from the service is a 405 Method Not Allowed. What am I doing wrong here?
UPDATE: The function in my mobile app that's uploading the file is below. This code previous worked fine when pointed to an older ASMX service.
ns.UploadImage = function(){
//alert(ns.Dictionary['LocalImagePath']);
var uri = ns.Dictionary['LocalImagePath'];
try {
var options = new FileUploadOptions();
options.fileKey = uri.substr(uri.lastIndexOf('/')+1) + ".jpeg";
options.fileName = uri.substr(uri.lastIndexOf('/')+1) + ".jpeg";
options.mimeType = "image/jpeg";
var ft = new FileTransfer();
ft.upload(uri, GetServerUrl()+"images.svc?file_key="+options.fileKey, ns.UploadImageSuccess, ns.UploadImageError, options);
} catch (e) {
ns.UploadImageError(e);
}
};
Ok so I think I figured this out. Apparently, when the method is hosted at the root like this, if you don't follow the name of the service in the uri with '/', the request won't get routed correctly. So, in the function that uploads the file, I changed the ft.upload line to the following:
ft.upload(uri, GetServerUrl()+"images.svc/?file_key="+options.fileKey, ns.UploadImageSuccess, ns.UploadImageError, options);
Which worked.