WCF Rest service not displaying methods on test client - c#

I am writing a WCF Rest service to return a JSON message. I've been trying to use an example I found on the internet as a guide. Any time I fire up the test client, none of my methods are displayed. Navigating to the Uri while the service is running yields me a "page cannot be displayed" page. Not exactly too sure where to go from here. Any help would be appreciated.
Web Config:
<system.serviceModel>
<bindings>
<webHttpBinding>
<binding name="webHttpBindingWithJasonP"
crossDomainScriptAccessEnabled="true" />
</webHttpBinding>
</bindings>
<services>
<service name="WcfRestLicense.LicenseService"
behaviorConfiguration="WebServiceBehavior">
<endpoint behaviorConfiguration="jsonBehavior"
binding="webHttpBinding"
bindingConfiguration="webHttpBindingWithJasonP"
contract="WcfRestLicense.ILicenseService" />
<endpoint contract="IMetadataExchange"
binding="mexHttpBinding"
address="mex" />
</service>
</services>
<!--<client />-->
<behaviors>
<endpointBehaviors>
<behavior name="jsonBehavior">
<webHttp />
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="WebServiceBehavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<protocolMapping>
<add
scheme="http"
binding="webHttpBinding"
bindingConfiguration="webHttpBindingWithJasonP" />
</protocolMapping>
<serviceHostingEnvironment
aspNetCompatibilityEnabled="false"
multipleSiteBindingsEnabled="true" />
Service method:
public IQueryable<customer> GetCustomerById(string customerId)
{
int custId = Convert.ToInt32(customerId);
return _context.customers.Where(c => c.cust_id == custId);
}
Interface:
[ServiceContract]
public interface ILicenseService
{
[OperationContract]
[WebGet(UriTemplate = "customer/{customerId}/",
RequestFormat= WebMessageFormat.Json,
ResponseFormat = WebMessageFormat.Json,
BodyStyle = WebMessageBodyStyle.Bare)]
IQueryable<customer> GetCustomerById(string customerId);
}

If by test client you're talking about the WcfTestClient, then it won't work with RESTful services; it's designed to work with SOAP based web services. You can test RESTful services in a browser by passing in the appropriate URI, something like this:
http://<location of your service>/service/1
Where the number 1 would be a customer ID. This is a rough example as a) I don't do a lot with RESTful services and b) I'm not sure what your actual address is.
As far as getting a 404 when you go to the Uri, it sounds like you're looking for the help page. You can enable that in your config file:
<bindings>
<webHttpBinding>
<binding name="webHttpBindingWithJasonP"
crossDomainScriptAccessEnabled="true"
enableHelp="true" />
</webHttpBinding>
</bindings>

Related

How can you receive an image sent from Android using WCF?

If you have a simple example of how you can receive an image using WCF and save that image in a custom folder, they would save me a lot of time and guide me on the right track.
I've seen that you can use the Stream type or the byte[] type, but I could not do it correctly.
Thank you very much for your time.
I have made a demo, wish it is useful to you.
Server (WCF service application)
[ServiceContract]
public interface IService1
{
[OperationContract]
[WebInvoke(Method ="POST",RequestFormat =WebMessageFormat.Json,ResponseFormat =WebMessageFormat.Json)]
Task UploadStream(Stream stream);
}
public class Service1 : IService1
{
public async Task UploadStream(Stream stream)
{
using (stream)
{
//save file to local folder
using (var file=File.Create(#"C:\"+Guid.NewGuid().ToString()+".png"))
{
await stream.CopyToAsync(file);
}
}
}
}
Web.config(wcf configuration)
<system.serviceModel>
<services>
<service name="WcfService3.Service1">
<endpoint address="" binding="webHttpBinding" contract="WcfService3.IService1" bindingConfiguration="mybinding" behaviorConfiguration="rest"></endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"></endpoint>
</service>
</services>
<bindings>
<webHttpBinding>
<binding name="mybinding" receiveTimeout="00:30:00" sendTimeout="00:30:00" maxReceivedMessageSize="104857600" transferMode="Streamed">
<security mode="None"></security>
</binding>
</webHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="rest">
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
<protocolMapping>
<add binding="basicHttpsBinding" scheme="https" />
</protocolMapping>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
</system.serviceModel>
For creating stream transfer mode service, we could also create soap service with BasicHttpBinding.
https://social.msdn.microsoft.com/Forums/vstudio/en-US/02733eae-a871-4655-9a2b-0ca1095b07ea/problems-when-uploading-a-stream-to-wcf?forum=wcf
On client end, you could use third-party library to call the WCF rest service, such as ksoap. But you also could send a http request with HttpClient library. Just like the following code snippets (HttpClient is .Net library, not java library, but the usage is similar).
class Program
{
static void Main(string[] args)
{
HttpClient client = new HttpClient();
HttpContent content = new StreamContent(File.OpenRead(#"2.png"));
Task.WaitAll(client.PostAsync("http://10.157.18.36:8800/service1.svc/UploadStream", content));
Console.WriteLine("OK");
}
}
Feel free to let me know if there is anything I can help with.
You want to consume an image response from a WCF endpoint?
An example here:
https://www.dotnetcurry.com/wcf/723/download-files-using-wcf-rest-endpoints

"localhost refused to connect" when calling wcf rest service

I created a wcf service with two different endpoints using basicHttpBinding and webHttpBinding. I have a asp mvc client consuming the basicHttpBinding endpoint and angular controller consuming the webHttpBinding. However when I call the endpoint using the webHttpBinding via browser and angular controller I am getting connection refused error. How can I fix this problem or what am I doing wrong (New to WCF).
Service Contract:
[ServiceContract]
public interface IVacationService
{
[WebInvoke(UriTemplate = "create",ResponseFormat = WebMessageFormat.Json)]
[OperationContract]
VacationDC RequestVacation(VacationDC vacation);
[WebGet(UriTemplate = "approved",ResponseFormat = WebMessageFormat.Json)]
[OperationContract]
IEnumerable<VacationDC> GetApprovedVacations();
[WebGet(UriTemplate = "all", ResponseFormat = WebMessageFormat.Json)]
[OperationContract]
IEnumerable<VacationDC> GetAllVacations();
[WebInvoke(UriTemplate = "remove/{id}", Method = "DELETE",RequestFormat = WebMessageFormat.Json)]
[OperationContract]
void RemoveVacation(long id);
}
Web.config:
<services>
<service name="WcfService.VacationService">
<endpoint address="basic" binding="basicHttpBinding" name="Soap" contract="WcfService.IVacationService" />
<endpoint address="api" binding="webHttpBinding" name="rest" contract="WcfService.IVacationService" behaviorConfiguration="webRest"/>
<host>
<baseAddresses>
<add baseAddress="http://localhost:8092/vacation" />
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<endpointBehaviors>
<behavior name="webRest">
<webHttp />
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>

Secure a Wcf json web service without Window authentication

I'd like to secure a web service. I have to avoid window authentication because the hosting company will cause me some problems
How is it possible ? The best option for me if to configure the user / password (or just the password. it would be enought for that web service) into the web.config file.
I imagine I can add a special parameter but it seems ugly
My configuration is :
<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="false" multipleSiteBindingsEnabled="true"/>
<services>
<service name="ct.WebServices.WsCT">
<endpoint address="" behaviorConfiguration="ct.WebServices.Service1AspNetAjaxBehavior" binding="webHttpBinding" contract="ct.WebServices.WsCT"/>
</service>
</services>
<behaviors>
<endpointBehaviors>
<behavior name="ct.WebServices.Service1AspNetAjaxBehavior">
<webHttp faultExceptionEnabled="true"/>
</behavior>
</endpointBehaviors>
</behaviors>
<bindings>
<webHttpBinding>
<binding>
<readerQuotas maxStringContentLength="1000000"/>
</binding>
</webHttpBinding>
</bindings>
</system.serviceModel>
The web service is used by android device
The code is :
namespace ct.WebServices
{
[ServiceContract(Namespace = "")]
[ServiceBehavior(IncludeExceptionDetailInFaults = true)]
public class WsCT
{
[OperationContract]
[WebGet(ResponseFormat = WebMessageFormat.Json, UriTemplate = "/modif")]
public IList<Ws.Modification> GetModifs() { return null; }
}
}

Calling a service method with serialised objects

I have a WCF service with a post method. This takes a single entity.
[OperationContract, FaultContract(typeof(ServiceError))]
[WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.Wrapped]
Entity SaveEntity(Entity entity);
I have a file with an xml serialised representation of these objects. I need to be able to post this xml to the service directly without deserialising it at the client side (architecture issues, we don't have the references).
Is it possible to do this by constructing a request with something like the HttpClient?
var client = new HttpClient(HttpClient:);
client.PostAsync("http://localhost:55217/MyService.svc/SaveEntity", new HttpContent
{
Headers = new System.Net.Http.Headers.HttpContentHeaders
{
// can I put my serialised xml here?
}
}
Here's the config:
<system.serviceModel>
<services>
<service behaviorConfiguration="Default" name="MyService">
<endpoint address="" binding="webHttpBinding" contract="IMyService" behaviorConfiguration="webBehavior" bindingConfiguration="fullMessageSize" />
<endpoint address="ws" binding="wsHttpBinding" contract="IMyService" bindingConfiguration="fullMessageSize" />
</service>
</services>
<behaviors>
<endpointBehaviors>
<behavior name="webBehavior">
<webHttp />
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="Default">
<serviceMetadata httpGetEnabled="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<webHttpBinding>
<binding name="fullMessageSize" maxReceivedMessageSize="104857600" />
</webHttpBinding>
<wsHttpBinding>
<binding name="fullMessageSize" maxReceivedMessageSize="104857600" />
</wsHttpBinding>
</bindings>
</system.serviceModel>
Why not create an intermediate service?
[OperationContract, FaultContract(typeof(ServiceError))]
[WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.Wrapped]
Entity SaveEntity(XElement entitySerialized)
{
var entity = Deserialize(entitySerialized);
var realService = new MyServiceClient();
return realService.SaveEntity(entity);
}
The intermediate service can have the references required for serialization.
You could consider creating a service-to-service endpoint for use between the intermediate service and the real service. That endpoint could use one of the faster bindings like netTcpBinding, that you might not want to use with your clients.

My page doesnt seem to let me do ajax calls to my service files methods

I get a error 400, Bad Request.
I have a set of pages that i was trying to write. (Listing only relevant)
./Webpage.aspx
./webservices/WebCalls.svc
./webservices/IWebCalls.cs
./Web.config
and i was looking all over to allow my frontend to communicate with the Webcalls page like follows:
$.ajax({
url: "webservices/WebCalls.svc/DoWork",
success: function(){
console.log(arguments);
}
});
but it doesnt seem to work.
I was thinking to create the files as such:
WebCalls.svc:
public class WebCalls: IWebCalls
{
public string DoWork()
{
return "{\"hello\":\"Chop Wood, Carry Water.\"}";
}
}
and IWebCalls.cs:
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]
public interface IWebCalls
{
[OperationContract]
[WebInvoke(Method = "GET",
ResponseFormat = WebMessageFormat.Json,
BodyStyle = WebMessageBodyStyle.Wrapped,
UriTemplate = "DoWork")]
string DoWork();
}
and in my webConfig, i thought i set it up correctly:
<behaviors>
<endpointBehaviors>
<behavior name="web">
<webHttp helpEnabled="true" />
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="ServiceBehavior">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" httpGetUrl=""/>
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
<behavior name="">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" aspNetCompatibilityEnabled="true" />
<services>
<service behaviorConfiguration="ServiceBehavior" name="MyProj.WebCalls">
<endpoint address="" behaviorConfiguration="web" binding="webHttpBinding"
bindingConfiguration="LargeWeb" name="LargeWeb" contract="MyProj.webservices.IWebCalls" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
</services>
<bindings>
<webHttpBinding>
<binding name="LargeWeb"
maxBufferPoolSize="15000000"
maxReceivedMessageSize="15000000"
maxBufferSize="15000000">
<readerQuotas
maxArrayLength="15000000"
maxBytesPerRead="15000000"
maxDepth="32"
maxNameTableCharCount="15000000"
maxStringContentLength="15000000"
/>
</binding>
</webHttpBinding>
</bindings>
When i run it, it just tells me that it has created a service, but when i try to call: DoWork it gets a 400 error.
Am I doing something wrong with my approach? Im just trying to build up a set of pages such that i can query for data. Originally, i was going to create a GenericHander.asxh for EACH function i wanted to create, but i thought that was too much space. I knew something like this was an option, but it seems that it doesnt work.
You may have decorated the wrong interface ITestService. Instead check the declaration of IWebCalls.
EDIT: Hmm.. I see you updated question ...
I think your services name should probably be name="MyProj.webservices.WebCalls" - but assuming that too is a typo, the only issue I see is that mex endpoint should not be there. mex endpoints are not meant for REST based services.

Categories