Exposing wcf service metadata - c#

I'm following a tutorial on setting up a wcf service. I finished the changes it talks about, up to the first time it says to start the service. When navigating to the endpoint in my web browser I either get a 404 or 403.14 error. Initially the service was showing the folder structure, but I removed the attribute in the web.config file that was enabling that. I'm sure the issue is related to that file, but I'm not sure what else to change.
Link to the guide: http://www.c-sharpcorner.com/UploadFile/dhananjaycoder/four-steps-to-create-first-wcf-service-for-beginners/
Web.config file:
<?xml version="1.0"?>
<configuration>
<appSettings>
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true"/>
</appSettings>
<system.web>
<compilation debug="true" targetFramework="4.5.2"/>
<httpRuntime targetFramework="4.5.2"/>
<httpModules>
<add name="ApplicationInsightsWebTracking" type="Microsoft.ApplicationInsights.Web.ApplicationInsightsHttpModule, Microsoft.AI.Web"/>
</httpModules>
</system.web>
<system.serviceModel>
<services>
<service name="WcfCalculator.Calculator" behaviorConfiguration="Metadata">
<endpoint address="" contract="WcfCalculator.ICalculator" binding="basicHttpBinding"/>
<endpoint name="mex" address="mex" contract="IMetadataExchange" binding="mexHttpBinding"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="Metadata">
<serviceMetadata httpGetEnabled="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="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
<protocolMapping>
<add binding="basicHttpsBinding" scheme="https"/>
</protocolMapping>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true"/>
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true">
<remove name="ApplicationInsightsWebTracking"/>
<add name="ApplicationInsightsWebTracking" type="Microsoft.ApplicationInsights.Web.ApplicationInsightsHttpModule, Microsoft.AI.Web"
preCondition="managedHandler"/>
</modules>
<!--
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.
-->
<validation validateIntegratedModeConfiguration="false"/>
</system.webServer>
</configuration>
Service Contract:
using System.ServiceModel;
namespace WcfCalculator
{
[ServiceContract]
public interface ICalculator
{
[OperationContract]
double AddNumbers(double number1, double number2);
[OperationContract]
double SubstractNumbers(double number1, double number2);
[OperationContract]
double MultiplyNumbers(double number1, double number2);
[OperationContract]
double DivisionNumbers(double number1, double number2);
}
}

I think the 403.14 may be related to your folder permissions. What account is your application pool running under and the version of .NET Framework? Make sure you're app pool is targeting Framework 4.0. 403.14 - most likely you're trying to browse the root directory and directory browsing is disabled in IIS or your app pool doesn't have enough permissions. Than, try removing protocolMapping.
In VS2015 you can set .svc file as a start up document. Hitting "F5" will open that document in WCF Test Client (WcfTestClient.exe). Alternatively, you can right-click the .svc file and select "View in Browser".

Related

WCF url allow user not to input parameter

I have another WCF related question although this one looks relatively simple.
I have a method that looks like this:
[OperationContract()]
[WebInvoke(Method = "GET", ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Bare, RequestFormat = WebMessageFormat.Json, UriTemplate = "/BS/vFacility/{vFacility}/vAdress/{vAdress}/vPostalNr/{vPostalNr})]
string BS(string vFacility, string vAdress, string vPostalNr);
This works if I call it like this:
/BS/vFacility/Oven/vAdress/Boulevard 25/vPostalNr/6749
but I would for the user to be able to call this method through an url and then not input, like an adress, like this:
/BS/vFacility/Oven/vAdress//vPostalNr/6749
In this case I would like the ignored parameter to be set to null if possible.
If I try the above url I get a message stating "endpoint was not found"
This is my web.config:
<?xml version="1.0"?>
<configuration>
<appSettings>
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
</appSettings>
<system.web>
<compilation debug="true" targetFramework="4.6.1"/>
<pages validateRequest="false" />
<httpRuntime targetFramework="4.6.1"/>
</system.web>
<system.serviceModel>
<behaviors>
<serviceBehaviors >
<behavior name="ServiceBehavior">
<!-- To avoid disclosing metadata information, set the values below to false 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>
</endpointBehaviors>
</behaviors>
<services>
<service name="WCFBolig.Service1" behaviorConfiguration="ServiceBehavior">
<endpoint binding="webHttpBinding"
contract="WCFBolig.IService1"
behaviorConfiguration="web"/>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
</services>
<serviceHostingEnvironment 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=XX;database=XX;user=XX;password=XX"
providerName="System.Data.SqlClient"
/>
</connectionStrings>
</configuration>
Is this possible or are users forced to giving inputs for all parameters?
I just needed to learn a bit about URIs to do this. Turns out I had to change it from this:
/BS/vFacility/{vFacility}/vAdress/{vAdress}/vPostalNr/{vPostalNr}
To This:
/BS?vFacility={vFacility}&vAdress={vAdress}&vPostalNr={vPostalNr}
Now I can simply ignore parameters and it still works. Do have to make sure the SQL code will still work with null values though.
F.eks. urls like this(http://localhost/BAlias/Service1.svc/BS?) or this(http://localhost/BAlias/Service1.svc/BS?vAdress=Whateverroad) now work just fine.

Web Service 404 Error

I have created a web service that returns JSON data. It works correctly when accessing through my local host.
http://localhost:6553/Service1.svc/GetViewData
but when I deploy and try to run on my production server I get the following error:
Server Error in '/JSONWebService' Application.
The resource cannot be found.
Description: HTTP 404. The resource you are looking for (or one of its dependencies) could have been removed, had its name changed, or is temporarily unavailable. Please review the following URL and make sure that it is spelled correctly.
Requested URL: /JSONWebService/Service1.svc/GetViewData
If I remove the /GetViewData from the URL I get the following message:
Server Error in '/JSONWebService' Application.
The resource cannot be found.
Description: HTTP 404. The resource you are looking for (or one of its dependencies) could have been removed, had its name changed, or is temporarily unavailable. Please review the following URL and make sure that it is spelled correctly.
Requested URL: /JSONWebService/Service1.svc/GetViewData
If I remove the /GetViewData from the URL I get the following message:
You have created a service.
To test this service, you will need to create a client and use it to call the service. You can do this using the svcutil.exe tool from the command line with the following syntax:
svcutil.exe http://ac.gtest.oh.edu/JSONWebService/Service1.svc?wsdl
Here is my web config:
<?xml version="1.0"?>
<configuration>
<connectionStrings>
<add name="Web_TransferConnectionString" connectionString="Data Source=dart;Initial Catalog=Web_Transfer;Integrated Security=True"
providerName="System.Data.SqlClient" />
</connectionStrings>
<appSettings>
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true"/>
</appSettings>
<system.web>
<compilation targetFramework="4.5"/>
<httpRuntime targetFramework="4.5"/>
<httpModules>
<add name="ApplicationInsightsWebTracking" type="Microsoft.ApplicationInsights.Web.ApplicationInsightsHttpModule, Microsoft.AI.Web"/>
</httpModules>
</system.web>
<system.serviceModel>
<services>
<service name="JSONWebService.Service1">
<endpoint address="../Service1.svc" binding="webHttpBinding" contract="JSONWebService.IService1" behaviorConfiguration="webBehaviour" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior>
<!-- To avoid disclosing metadata information, set the values below to false before deployment -->
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="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="false"/>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="webBehaviour">
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
<protocolMapping>
<add binding="basicHttpsBinding" scheme="https"/>
</protocolMapping>
<!-- <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true">
<baseAddressPrefixFilters>
<add prefix="http://www.JSONWebService.com/"/>
</baseAddressPrefixFilters>
</serviceHostingEnvironment> -->
</system.serviceModel>
<system.webServer>
<!-- <httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Headers" value="Content-Type, Accept"/>
</customHeaders>
</httpProtocol> -->
<modules runAllManagedModulesForAllRequests="true">
<remove name="ApplicationInsightsWebTracking"/>
<add name="ApplicationInsightsWebTracking" type="Microsoft.ApplicationInsights.Web.ApplicationInsightsHttpModule, Microsoft.AI.Web"
preCondition="managedHandler"/>
</modules>
<!--
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"/>
<validation validateIntegratedModeConfiguration="false"/>
IService1.cs file:
public interface IService1
{
[OperationContract]
[WebInvoke(Method = "GET", ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Wrapped, UriTemplate = "GetViewData")]
//string GetData(string value);
List<wsUpcomingDissertationsView> GetViewData();
[OperationContract]
CompositeType GetDataUsingDataContract(CompositeType composite);
// TODO: Add your service operations here
}
Service1.svc.cs
public class Service1 : IService1
{
//public string GetData(string value)
//{
// return string.Format("You entered: {0}", value);
//}
public List<wsUpcomingDissertationsView> GetViewData()
{
Upcoming_Dissertations_ViewDataContext dc = new Upcoming_Dissertations_ViewDataContext();
List<wsUpcomingDissertationsView> results = new List<wsUpcomingDissertationsView>();
foreach (Upcoming_Dissertations_View UDV in dc.Upcoming_Dissertations_Views)
{
results.Add(new wsUpcomingDissertationsView()
{
First_Name = UDV.FIRST_NAME,
Last_Name = UDV.LAST_NAME,
exam_oral_date = UDV.exam_oral_date,
Expr1 = UDV.Expr1,
});
}
return results;
}
UPDATE:
I got it to work after hours of trial and error. I made some modifications:
<system.serviceModel>
<services>
<service name="JSONWebService.Service1">
<endpoint address="" binding="webHttpBinding" contract="JSONWebService.IService1" bindingConfiguration="webBinding" behaviorConfiguration="webBehaviour"/>
</service>
</services>
<bindings>
<webHttpBinding>
<binding name="webBinding">
<security mode="Transport">
</security>
</binding>
</webHttpBinding>
</bindings>

Method Not Found using WCF POST Method

<ServiceContract()>
Public Interface IService1
<OperationContract()>
<WebInvoke(Method:="POST", UriTemplate:="InsertData/{name}/{Surname}")>
Function InsertData(ByVal name As String, ByVal surname As String) As String
End Interface
Implemented it
Public Class Service1
Implements IService1
Public Function InsertData(name As String, surname As String) As String Implements IService1.InsertData
' Save name and surname which does work
End Function
End Class
My web.config
<system.web>
<compilation debug="true" strict="false" explicit="true" targetFramework="4.5" />
<httpRuntime targetFramework="4.5"/>
</system.web>
<system.serviceModel>
<services>
<service name="WcfParameters.Service1">
<endpoint address="http://localhost:12345/Service1.svc" behaviorConfiguration="webHttpBinding"
binding="webHttpBinding" bindingConfiguration="" name="WebHttpw"
contract="WcfParameters.IService1" />
<!--<endpoint contract="IMetadataExchange" binding="mexHttpBinding" address="mex" />-->
</service>
</services>
<client>
<endpoint address="http://localhost:12345/Service1.svc" binding="webHttpBinding"
bindingConfiguration="" contract="WcfParameters.IService1" />
</client>
<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="false"/>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="webHttpBinding">
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
<!--<protocolMapping>
<add binding="basicHttpsBinding" scheme="https" />
</protocolMapping>-->
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="false" />
</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>
</configuration>
I am trying to create a service which will accept a few parameters and save the data to my database.
Using the above configuration if i navigate to http://localhost:12345/Service1.svc/InsertData/name/surname i get the error "Method Not Found"
If i do the same POST method and run it in Fiddler then it saves to the database successfully.
I then used this link http://blogs.msdn.com/b/carlosfigueira/archive/2012/03/26/mixing-add-service-reference-and-wcf-web-http-a-k-a-rest-endpoint-does-not-work.aspx as a guide but i think ive used as much info in order to accomplish what i think i need (i could be wrong).
Should i be doing something different?
Using the above configuration if i navigate to
http://localhost:12345/Service1.svc/InsertData/name/surname i get the
error "Method Not Found"
When you do this trough your browser you are actually doing a GET request, which your method does not support.
When you do it trough Fiddler you issue a POST.
You can do a POST using the WebRequest class or HttpRequest trough your code.

Web Service Rest Error http 400

I have a WebService that I use only for data.
Using the service:
[WebGet(UriTemplate = "maq/?v={v}",
RequestFormat = WebMessageFormat.Xml,
ResponseFormat = WebMessageFormat.Xml)]
[OperationContract]
List<VoltaPDA> GetAllta(int v);
it works perfectly;
using this function in the same webService:
[WebGet(UriTemplate = "ped/?T={ti}&V={Vo}",
RequestFormat = WebMessageFormat.Xml,
ResponseFormat = WebMessageFormat.Xml)]
[OperationContract]
List<Pedido> GetSub(string ti,string Vo);
I get the error HTTP 400 The curious that the test through a browser directly both work, when I use them on my Windows Mobile 6.5 application the second function returns HTTP 400 error.;
Can you imagine what it might be?
Both access the same databaseSql Server 2012 , and the WebService hosted in IIS 8.5
webConfig:
<?xml version="1.0"?>
<configuration>
<connectionStrings>
<add name="BD_S_V10ConnectionString" connectionString="Data Source=NUNO-PC;Initial Catalog=BD_S_V10;Integrated Security=True" providerName="System.Data.SqlClient"/>
</connectionStrings>
<system.web>
<compilation debug="true" targetFramework="4.0"/>
<globalization culture="pt-PT" uiCulture="pt-PT" />
</system.web>
<system.serviceModel>
<!-- REST -->
<services>
<service name="WcfServicePedido_v7.ServicePedido">
<endpoint name="RestEndPoint" contract="WcfServicePedido_v7.IServicePedido" binding="webHttpBinding" address="" behaviorConfiguration="restBehavior"/>
</service>
</services>
<behaviors>
<endpointBehaviors>
<behavior name="restBehavior">
<webHttp helpEnabled="true"/>
</behavior>
</endpointBehaviors>
<!-- REST -->
<serviceBehaviors>
<behavior>
<!-- To avoid disclosing metadata information, set the value below to false 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"/>
<!--
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.diagnostics>
<sources>
<source name="System.ServiceModel" switchValue="Information, ActivityTracing" propagateActivity="true">
<listeners>
<add name="traceListener" type="System.Diagnostics.XmlWriterTraceListener" initializeData="Traces.svclog" traceOutputOptions="LogicalOperationStack, DateTime, Timestamp, ProcessId, ThreadId"/>
</listeners>
</source>
</sources>
</system.diagnostics>
</configuration>
It is common that the Default 400 response is returned for Mime-Type mismatches and malformed requests (body and sometime URLs) from the client.
In this case, I would recommend checking the Content-Type header sent from the mobile application in the second request to make sure its something like text/xml.

WCF endpoint not found

I'm following a tutorial in a book to implement push notifications for Windows Phone. This is the markup of the service:
<%# ServiceHost Language="C#" Debug="true" Service="Service.PushService" CodeBehind="PushService.svc.cs" Factory="System.ServiceModel.Activation.WebServiceHostFactory" %>
As you see, a factory is added, although I don't really understand what it's for. When running the service, I get a "endpoint not found" error. When I remove the factory from the markup, the error disappears, but I get an empty page.
Any idea what could cause this error or how to fix it? If you need more code, please tell me.
Thanks
EDIT:
My web.config:
<?xml version="1.0"?>
<configuration>
<appSettings>
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
</appSettings>
<system.web>
<compilation debug="true" targetFramework="4.5" />
<httpRuntime targetFramework="4.5"/>
</system.web>
<system.serviceModel>
<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="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
<protocolMapping>
<add binding="basicHttpsBinding" scheme="https" />
</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>
</configuration>
You are missing the endpoint configuration in your web.config.
Add this to your web.config:
<system.serviceModel>
<services>
<service name="Service.PushService">
<endpoint address="" binding="basicHttpsBinding"
contract="Service.IPushService" />
</service>
</services>
</system.serviceModel>
For those who absently implement the method in Service.svc that its definition is absent in IService causes the same exception.
This is forgotten
[OperationContract]
string CheckHMAC(string hMac);
But implemented
[WebInvoke(Method = "GET", UriTemplate = "/CheckHMAC/{hMac}")]
public string CheckHMAC(string hMac)
{//}

Categories