I have the WCF service contract:
[ServiceContract]
public interface IVLSContentService
{
[OperationContract]
[WebInvoke(Method = "GET", ResponseFormat = WebMessageFormat.Xml, UriTemplate = "GetCategoriesGET/{userIdArg}", BodyStyle = WebMessageBodyStyle.Bare)]
List<Video> GetVideosGET(string userIdArg);
[WebInvoke(Method = "POST",BodyStyle=WebMessageBodyStyle.Wrapped, UriTemplate = "submit")]
[OperationContract]
void SubmitVideoPOST(Video videoArg, string userId);
}
And I have the service that implements the contract:
public class VLSContentService : IVLSContentService
{
List<Video> catsForUser1 = new List<Video>();
List<Video> catsForUser2 = new List<Video>();
public List<Video> GetVideosGET(string userIdArg)
{
List<Video> catsToReturn = new List<Video>();
if (Int32.Parse(userIdArg) == 1)
{
catsToReturn = catsForUser1;
}
else if (Int32.Parse(userIdArg) == 2)
{
catsToReturn = catsForUser2;
}
return catsToReturn;
}
public void SubmitVideoPOST(Video videoArg, string userId)
{
int i = 0;
}
}
And I have the configuration:
<system.serviceModel>
<services>
<service behaviorConfiguration="VLSContentServiceBehaviour" name="VLSContentService">
<endpoint address="" behaviorConfiguration="VLSContentServiceEndpointBehaviour" binding="webHttpBinding" contract="IVLSContentService"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="VLSContentServiceBehaviour">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="VLSContentServiceEndpointBehaviour">
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
</system.serviceModel>
And I am trying to call the POST WCF operation with the following client code:
static void Main(string[] args)
{
WebChannelFactory<IVLSContentService> cs = new WebChannelFactory<IVLSContentService>(new Uri("http://localhost:52587/Api/Content/VLSContentService.svc/SubmitVideoPOST"));
IVLSContentService client = cs.CreateChannel();
Video videoToAdd = new Video("My First Video");
client.SubmitVideoPOST(videoToAdd,"1");
}
But im getting this error and I cant work out why:
There was no endpoint listening at
http://localhost:52587/Api/Content/VLSContentService.svc/SubmitVideoPOST/submit
that could accept the message. This is
often caused by an incorrect address
or SOAP action. See InnerException, if
present, for more details.
I know when I browse to the GET method in a URL and I pass the correct parameters I am getting xml back but my POST method just doesnt work. Ive copied the example from pluralsight the only difference is um trying to host the service in .svc file instead of service host application...
Can anybody point me in the right direction?
Looks like you have the address of the service wrong
You should be posting to http://localhost:52587/Api/Content/VLSContentService.svc/submit
The UriTemplate is relative to the address of the endpoint which is
http://localhost:52587/Api/Content/VLSContentService.svc
Change this line of code to
WebChannelFactory cs = new WebChannelFactory(new Uri("http://localhost:52587/Api/Content/VLSContentService.svc/"));
You appear to be posting to the wrong URL. The error shows you posting to the relative address "/SubmitVideoPOST/submit", but your UriTemplate for that method is just "/submit".
You do not need to include the .NET method name in the URL for REST based requests. Only the UriTemplate matters. Mapping to the correct runtime method is done for you by the WCF REST UriTemplate processing engine.
Related
Here is my wcf service method:
[WebInvoke(Method = "GET", ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Bare, UriTemplate = "/CheckID/{id}")]
public string CheckID(string id)
{
/*Check reuqest where it comes from */
}
I want my method send response OK if it comes/is invoked from http://particularIP.com, unless response Bad request.
How can i do that?
You can use IP Filter in web.config file, like :-
<serviceBehaviors>
<behavior name="ServiceBehaviour">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
<behavior name="RestrictedServiceBehaviour">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
<IPFilter filter="172.*.*.* 127.0.0.1" />
</behavior>
</serviceBehaviors>
Edited
Or use can ServiceAuthorizationManager.CheckAccessCore in which you get client IP from OperationContext.
https://msdn.microsoft.com/en-us/library/system.servicemodel.serviceauthorizationmanager.checkaccesscore.aspx
Edit 2
using System.ServiceModel;
using System.ServiceModel.Channels;
OperationContext context = OperationContext.Current;
MessageProperties prop = context.IncomingMessageProperties;
RemoteEndpointMessageProperty endpoint =
prop[RemoteEndpointMessageProperty.Name] as RemoteEndpointMessageProperty;
string ip = endpoint.Address;
I have to call a WCF service. The WCF service is on and I can edit its configuration.
I want to create a client that calls the service. I cannot add the service reference to my client, so I am trying to call it with a HttpClient.
The client side code:
using (var client = new HttpClient())
{
//soapString is my input class serialized
var content = new StringContent(soapString, Encoding.UTF8, "text/xml");
using (var postResponse = client.PostAsync("http://localhost:52937/Attempts.svc/", content).Result)
{
string postResult = postResponse.Content.ReadAsStringAsync().Result;
}
}
The server side code:
[ServiceContract]
public interface IAttempts
{
[OperationContract]
void ReceiveAttemptResult(ReceiveAttemptResultInput result);
}
public class Attempts : IAttempts
{
string _backendUrl;
public void ReceiveAttemptResult(ReceiveAttemptResultInput result)
{
//...
}
}
And in the end the web.config server side:
<system.serviceModel>
<services>
<service name="it.MC.Listeners.Attempts">
<endpoint address="" contract="it.MC.Listeners.IAttempts" binding="basicHttpBinding"/>
<endpoint address="mex" contract="IMetadataExchange" binding="mexHttpBinding"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
</system.serviceModel>
When I call the service, I just obtain an empty string and I cannot stop in debug inside the service... What's wrong?
Thank you
Just in case this bedevils anyone else. Thank you #Disappointed for your missing piece of the puzzle, it prompted me to run the thing in WCF Test Client with Fiddler open to see what I was missing:
HttpClient httpClient = new HttpClient();
httpClient.DefaultRequestHeaders.Add("SOAPAction", "http://tempuri.org/IMyService/Mymethod_Async");
string soapEnvelope = "<s:Envelope xmlns:s= \"http://schemas.xmlsoap.org/soap/envelope/\"><s:Body><Mymethod_Async xmlns=\"http://tempuri.org/\"/></s:Body></s:Envelope>";
var content = new StringContent(soapEnvelope, Encoding.UTF8, "text/xml");
HttpResponseMessage hrm = httpClient.PostAsync("http://MyService.MyDomain.com/MyService.svc", content).Result;
I have a WCF Service with a SOAP endpoint. I added a REST endpoint and the Get methods are working just fine. I am having trouble with a POST method which takes in an object and returns a different object. When I pass in my object, I get this error back:
"Message":"Object reference not set to an instance of an object."
Here's the code to call the service:
string URL = "http://qa.acct.webservice";
HttpClient client = new HttpClient();
client.BaseAddress = new Uri(URL);
// Add an Accept header for JSON format.
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
// HTTP POST
var request = new RequestGetInventory
{
BrandIDs = new string[] { "4", "42" },
AccountID = "9900003"
};
var resp = client.PostAsJsonAsync("/AxaptaService.svc/rest/GetInventory", request);
response = resp.Result;
if (response.IsSuccessStatusCode)
{
var temp = response.Content.ReadAsStringAsync().Result;
MessageBox.Show(temp); //error message received here.
}
The RequestGetInventory object is defined as follows:
[DataContract]
public class RequestGetInventory
{
[DataMember]
public string[] BrandIDs { get; set; }
[DataMember]
public string AccountID { get; set; }
}
The contract for the webservice is defined as follows:
[OperationContract]
[WebInvoke(Method = "POST",
RequestFormat = WebMessageFormat.Json,
BodyStyle = WebMessageBodyStyle.WrappedRequest,
ResponseFormat = WebMessageFormat.Json)]
ResponseGetInventory GetInventory(RequestGetInventory Request);
I tried playing around with the WebInvoke parameters, but received the same error message for all viable attempts.
And this is how my web.config is set up:
<system.serviceModel>
<services>
<service behaviorConfiguration="" name="Proj.AxaptaUS.WebService.AxaptaService">
<endpoint address="rest" behaviorConfiguration="webBehavior" binding="webHttpBinding" contract="Proj.Interfaces.Axapta3.IAxaptaService"></endpoint>
<endpoint address="" binding="basicHttpBinding" contract="Proj.Interfaces.Axapta3.IAxaptaService"></endpoint>
</service>
</services>
<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="webBehavior">
<webHttp helpEnabled="true" />
<enableWebScript/>
</behavior>
</endpointBehaviors>
</behaviors>
<protocolMapping>
<add binding="basicHttpsBinding" scheme="https" />
</protocolMapping>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
</system.serviceModel>
I am not entirely sure what I'm doing wrong because I can access this using SOAP just fine. It seems like it is not getting any values for the object which I passed in, thus causing the object reference error.
Any help would be greatly appreciated! Thanks!
#jstreet posted a comment which ended up working.
I changed BodyStyle = WebMessageBodyStyle.WrappedRequest to BodyStyle = WebMessageBodyStyle.Bare and removed <enableWebScript/> from config file.
After doing those things, it started to work correctly! thanks #jstreet!
I am trying to create a JSON WCF web service.
I'm totally unclear on the whole process really! I'm connecting to MySQL DB on my Server.
So I have the following code:
My Interface -
[ServiceContract]
public interface IService1
{
[OperationContract]
[WebInvoke(Method = "GET", ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Wrapped, UriTemplate = "/GetAllResources")]
List<Resources> GetAllResources();
[OperationContract]
[WebInvoke(Method = "POST", ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Wrapped, UriTemplate = "/AddRoom")]
void AddRoom(string location, string name);
...
My Service -
[ScriptService]
public class Service1 : IService1
{
[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public void AddRoom(string location, string name)
{
String conString = System.Configuration.ConfigurationManager.ConnectionStrings["MyDatabaseConnectionString"].ConnectionString;
using (MySqlConnection cnn = new MySqlConnection(conString))
{
cnn.Open();
String sql = String.Format("INSERT INTO rooms(roomLocation, roomName) VALUES ({0}, {1});", location, name);
MySqlCommand cmd = new MySqlCommand(sql, cnn);
//doesn't return any rows
cmd.ExecuteNonQuery();
}
}
[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public List<Resources> GetAllResources()
{
String conString = System.Configuration.ConfigurationManager.ConnectionStrings["MyDatabaseConnectionString"].ConnectionString;
List<Resources> al = new List<Resources>();
using (MySqlConnection cnn = new MySqlConnection(conString))
{
cnn.Open();
String sql = String.Format("select * from resources");
MySqlCommand cmd = new MySqlCommand(sql, cnn);
MySqlDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
al.Add((Resources)reader[0]);
}
return al;
}
}
...
Web Config -
...
<system.web.extensions>
<scripting>
<webServices>
<jsonSerialization maxJsonLength="5000"/>
</webServices>
</scripting>
</system.web.extensions>
<system.web>
<compilation debug="true" targetFramework="4.5" />
<httpRuntime targetFramework="4.5"/>
</system.web>
<system.serviceModel>
<services>
<service name="RoomBookingService.Service1" behaviorConfiguration="RoomBookingServiceBehavior">
<endpoint address="../Service1.svc"
binding="webHttpBinding"
contract="RoomBookingService.IService1"
behaviorConfiguration="webBehaviour" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="RoomBookingServiceBehavior">
<!-- 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="webBehaviour">
<webHttp automaticFormatSelectionEnabled="true"/>
</behavior>
</endpointBehaviors>
</behaviors>
...
Is this correct?? What tools can I use to test the service? I have dropped it onto the server and tried downloading a few testing tools but they don't give me any errors just that it's not returning JSON?!
I will be creating an Android app to talk to the Service, but as this will also be a learning curve I want to know that my service works correctly before adding in another layer of complexity.
Any help or comments on my code or my issue would be greatly appreciated.
Thank you for your time
I managed to get it working:
Here is my code:
Contract:
namespace RoomBookingService
{
// NOTE: You can use the "Rename" command on the "Refactor" menu to change the interface name "IService1" in both code and config file together.
[ServiceContract]
public interface IService1
{
[OperationContract]
[WebGet(ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Wrapped, UriTemplate = "GetAllResources")]
String GetAllResources();
Service
[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public String GetAllResources()
{
String conString = System.Configuration.ConfigurationManager.ConnectionStrings["MyDatabaseConnectionString"].ConnectionString;
List<Dictionary<string, object>> tableRows = new List<Dictionary<string, object>>();
Dictionary<string, object> row= new Dictionary<string,object>();
DataTable dt = new DataTable();
System.Web.Script.Serialization.JavaScriptSerializer serializer =
new System.Web.Script.Serialization.JavaScriptSerializer();
try
{
using (MySqlConnection cnn = new MySqlConnection(conString))
{
cnn.Open();
String sql = String.Format("select resourceID, resourceName, resourceDesc, roomID from resources");
MySqlCommand cmd = new MySqlCommand(sql, cnn);
MySqlDataReader reader = cmd.ExecuteReader();
dt.Load(reader);
foreach (DataRow dr in dt.Rows)
{
row = new Dictionary<String, Object>();
foreach (DataColumn col in dt.Columns)
{
row.Add(col.ColumnName, dr[col]);
}
tableRows.Add(row);
}
return serializer.Serialize(tableRows);
}
}
catch (Exception ex)
{
return ex.ToString();
}
}
WebConfig
<system.web.extensions>
<scripting>
<webServices>
<jsonSerialization maxJsonLength="5000"/>
</webServices>
</scripting>
</system.web.extensions>
<system.web>
<compilation debug="true" targetFramework="4.5" />
<httpRuntime targetFramework="4.5"/>
</system.web>
<system.serviceModel>
<services>
<service name="RoomBookingService.Service1" behaviorConfiguration="RoomBookingServiceBehavior">
<endpoint address=""
binding="webHttpBinding"
contract="RoomBookingService.IService1"
behaviorConfiguration="webBehaviour" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="RoomBookingServiceBehavior">
<!-- 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="webBehaviour">
<webHttp automaticFormatSelectionEnabled="true"/>
</behavior>
</endpointBehaviors>
Still not absultely clear on everything but it's working!! So I'll go with that :-)
Thanks!
IService.cs
[OperationContract]
[WebGet(UriTemplate = "/IsValidUser?userid={userid}&password={password}", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
string IsValidUser(string userid, string password);
Service.cs
public string IsValidUser(string userid, string password)
{
if (userid =="bob" && password =="bob")
{
return "True";
}
else
{
return "false";
}
}
web.config
<?xml version="1.0"?>
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0">
<assemblies>
<add assembly="System.Data.Linq, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
<add assembly="mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
</assemblies>
</compilation>
</system.web>
<system.serviceModel>
<services>
<service name="Service" behaviorConfiguration="ServBehave">
<!--Endpoint for REST-->
<endpoint address="rest" binding="webHttpBinding" behaviorConfiguration="restPoxBehavior" contract="IService"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="ServBehave">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<!--Behavior for the REST endpoint for Help enability-->
<behavior name="restPoxBehavior">
<webHttp helpEnabled="true"/>
</behavior>
</endpointBehaviors>
</behaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true"/>
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
</system.webServer>
</configuration>
Problem:
Here my problem is that I want to pass multiple parameter while calling a WCF rest service, but I am not able to pass multiple parameters to that WCF rest service. I want to pass userid and password and check for in it. If it is bob then allow to go ahead.
And when I am calling this url:
http://localhost:48401/ARService/Service.svc/rest/IsValidUser?userid=bob&password=bob
then I am getting this error on my web page:
Endpoint not found. Please see the service help page for constructing valid requests to the service.
If somebody have idea how to call IsValidUser in my case with this function parameter. Please help me.
you can write this way:
Iservice.cs
[OperationContract]
[WebGet(UriTemplate = "IsValidUser/{userid}/{password}")]
string IsValidUser(string userid, string password);
service .cs
public string IsValidUser(string userid, string password)
{
if (userid== "root" && password== "root")
{
return "True";
}
else
{
return "false";
}
}
Run this Url in Browser,then you will get output
localhost/service.svc/rest/IsValidUser/root/root
try this
[OperationContract]
[WebGet(UriTemplate = "IsValidUser?userid={userid}&password={password}", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
string IsValidUser(string userid, string password);
Add BodyStyle on OperationContract
[WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.WrappedRequest)]