<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.
Related
I have a WCF application and some clients in my solution. What is the problem - when i try to access any method implemented in service from client, i get this error. I correctly added service references to every client and my Web.config file is shown below.
I already included detailed exceptions in my web config file and after that, i keep getting this error.
I already tried to debug my code and see which part throws exception, but it happens when i'm running client, and error is on server side. Could problem be in my static constructors in my server class?
<?xml version="1.0"?>
<configuration>
<appSettings>
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
</appSettings>
<system.web>
<compilation debug="true" targetFramework="4.6.1" />
<httpRuntime targetFramework="4.6.1"/>
</system.web>
<system.serviceModel>
<services>
<service name="Service.Service" behaviorConfiguration="debug">
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"></endpoint>
<endpoint address="AlarmDisplay" binding="wsDualHttpBinding" contract="Service.IAlarm"></endpoint>
<endpoint address="AlarmDisplay/Mex" binding="mexHttpBinding" contract="IMetadataExchange"></endpoint>
<endpoint address="DatabaseManager" binding="basicHttpBinding" contract="Service.IDatabaseManager"></endpoint>
<endpoint address="DatabaseManager/Mex" binding="mexHttpBinding" contract="IMetadataExchange"></endpoint>
<endpoint address="RealTimeUnit" binding="basicHttpBinding" contract="Service.IRealTimeUnit"></endpoint>
<endpoint address="RealTimeUnit/Mex" binding="mexHttpBinding" contract="IMetadataExchange"></endpoint>
<endpoint address="Trending" binding="wsDualHttpBinding" contract="Service.ITrending"></endpoint>
<endpoint address="Trending/Mex" binding="mexHttpBinding" contract="IMetadataExchange"></endpoint>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="debug">
<serviceDebug includeExceptionDetailInFaults="true" />
<serviceMetadata/>
</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="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>
And this is service file:
public class Service : IAlarm, IDatabaseManager, IRealTimeUnit, ITrending
{
static Dictionary<string, Tag> tags = new Dictionary<string, Tag>();
static Dictionary<string, Thread> threads = new Dictionary<string, Thread>();
static SimulationDriver simulationDriver = new SimulationDriver();
static RealTimeDriver realTimeDriver = new RealTimeDriver();
static IAlarmCallback alarmCallback = null;
delegate void AlarmDelegate(string message);
static event AlarmDelegate AlarmActivated = null;
static ITrendingCallback trendingCallback = null;
delegate void TrendingDelegate(int option, string type, string ID, double value);
static event TrendingDelegate ValueChanged = null;
static string scadaDirectory = #"C:\Users\Sevic\Desktop\SCADA\dir\";
static string configFile = #"scadaConfig.txt";
static string alarmFile = #"alarmLog.txt";
static string database = #"Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=C:\Users\Sevic\Desktop\SCADA\SCADA\Service\App_Data\DATABASE.mdf;Integrated Security=True";
static SqlConnection connection = new SqlConnection(database);
static bool serviceRunning = LoadConfigFile();
... implementation of methods
}
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.
I am learning WCF these days and probably don't know where to start. I want to create WCF REST Service, which will be accesible through HTTP requests (GET, PUT...). And at same time I want to be able to add this service as service reference or web reference and use them in the Web Application client as ordinary method. This issue is quite wide so I will by grateful for any hint or direction.
At this time, I have functional services and run them on my hosting. I can add Service Reference and Web Reference. Service reference is better for new code, as I reckognized, because it use WCF communication and thus it contains all former communication channels. When I add these references, I can use reference to GetSimpleDataService, but non of its methods. When I try to add these methods as reference, problem with metadata is noted.
WCF interface:
[ServiceContract]
public interface IGetSimpleDataService
{
[OperationContract]
[WebGet(UriTemplate = "User/{ID}")]
User GetUser(string ID);
[OperationContract]
[ScriptMethod(UseHttpGet = true)]
User GetUserByMethod(string ID);
[OperationContract]
[WebGet]
string ActivationTest();
[OperationContract]
[WebMethod]
string WebMethodTest();
}
Web.config:
<?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"/>
</system.web>
<system.serviceModel>
<services>
<service name="StoryHubWCFApp.TestStudentService" behaviorConfiguration="serviceBehavior">
<endpoint address=""
binding="webHttpBinding"
contract="StoryHubWCFApp.ITestStudentService"
behaviorConfiguration="web"
/>
</service>
<service name="StoryHubWCFApp.GetSimpleDataService" behaviorConfiguration="serviceBehavior">
<endpoint address=""
binding="webHttpBinding"
contract="StoryHubWCFApp.IGetSimpleDataService"
behaviorConfiguration="web"/>
</service>
</services>
<behaviors>
<endpointBehaviors>
<behavior name="web">
<webHttp />
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="serviceBehavior">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
<behavior name="">
<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>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
<directoryBrowse enabled="true"/>
</system.webServer>
</configuration>
Now I can get data via GET request, but I want to be able use service with Web/Service reference like this.:
string s = MyServices.ActivationTest();
I assume to use methods like this, which returns or takes values other than int and string I should have [DataContracts]? I understood too, I have to use [WebMethod] or [ScriptMethod], but I wasn't successful so far.
Thanks in regards for any correction.
You can so it almost as smoothly as your example shows...
Since your topic is quite broad I won't go in details just give pointers.
For your own classes, to be able to use them as parameters and/or return types. (in your case User) you have to define what and how to be serialized. You can read about that here:
https://msdn.microsoft.com/en-us/library/ms733127(v=vs.110).aspx
https://msdn.microsoft.com/en-us/library/ms733811(v=vs.110).aspx
Example:
[DataContract]
public class User
{
// This member is serialized.
[DataMember]
string FullName;
// This is not serialized because the DataMemberAttribute
// has not been applied.
private string MailingAddress;
}
Now you are able to use your class.
For calling the service:
You can add service reference: https://msdn.microsoft.com/en-us/library/bb386386.aspx (this would be a generated proxy to your service)
Or you can use ChannelFactory: https://msdn.microsoft.com/en-us/library/ms734681(v=vs.110).aspx
(with this you are in full control of the code, but might need to do more settings, i.e. endpoints.)
I have a class MessageInspector which implements IClientMessageInspector.
namespace WCFAuthentication
{
public class MessageInspector : IClientMessageInspector
{
public void AfterReceiveReply(ref System.ServiceModel.Channels.Message reply, object correlationState)
{
//throw new NotImplementedException();
Debug.WriteLine("IClientMessageInspector.AfterReceiveReply called.");
Debug.WriteLine("Message: {0}", reply.ToString());
}
public object BeforeSendRequest(ref System.ServiceModel.Channels.Message request, System.ServiceModel.IClientChannel channel)
{
//throw new NotImplementedException();
Debug.WriteLine("IClientMessageInspector.BeforeSendRequest called.");
return null;
}
}
}
I have configured this in my web.config of WCF :
<?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>
<extensions>
<behaviorExtensions>
<add
name="MessageInspector"
type="WCFAuthentication.MessageInspector, MessageInspector, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null"/>
</behaviorExtensions>
</extensions>
<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="restfulBehavior">
<webHttp/>
</behavior>
<behavior name="restfulBehavior_jwt">
<webHttp/>
<MessageInspector/>
</behavior>
</endpointBehaviors>
</behaviors>
<services>
<service name ="WCFAuthentication.Service1">
<endpoint address="" behaviorConfiguration="restfulBehavior_jwt" binding="webHttpBinding" contract="WCFAuthentication.IService1"/>
</service>
<service name ="WCFAuthentication.Authentication">
<endpoint address="" behaviorConfiguration="restfulBehavior" binding="webHttpBinding" contract="WCFAuthentication.IAuthentication"/>
</service>
</services>
<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>
While running wcf ( hosted in IIS), it is not able to recognize my "MessageInspector" class in the we config.
Server Error in '/WCFAuthentication' Application.
Configuration Error
Description: An error occurred during the processing of a configuration file required to service this request. Please review the specific error details below and modify your configuration file appropriately.
Parser Error Message: The type 'WCFAuthentication.MessageInspector, MessageInspector, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' registered for extension 'MessageInspector' could not be loaded.
Source Error:
Line 32: <behavior name="restfulBehavior_jwt">
Line 33: <webHttp/>
Line 34: <MessageInspector/>
Line 35: </behavior>
Line 36: </endpointBehaviors>
You can't add your MessageInspector directly that way, you need to implement an IEndpointBehavior as well as a BehaviorExtensionElement.
MSDN has a detailed example.
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)
{//}