WCF endpoint not found/method not allowed using Windows Service - javascript

I want to host my WCF web service on windows service so the front end can access the methods.
The service runs fine if I clicked on the service(view in Browser) in VS. But when I tired to host it using Windows Service, it's returning "Endpoint not found" from the browser when I used the base address and "Method Not Allow" When I specific the method that I want to access.
Below is my code:
Host's App.Config:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6" />
</startup>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="mexBehavior">
<serviceMetadata httpGetEnabled="true" />
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="jsonBehavior">
<webHttp defaultOutgoingResponseFormat="Json" />
</behavior>
</endpointBehaviors>
</behaviors>
<services>
<service behaviorConfiguration="mexBehavior" name="BestWebService.Service1">
<host>
<baseAddresses>
<add baseAddress="http://localhost/Service1.svc"/>
</baseAddresses>
</host>
<endpoint address="" binding="webHttpBinding" behaviorConfiguration="jsonBehavior"
contract="BestWebService.IService1"
bindingConfiguration="jsonBinding">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
</service>
</services>
<bindings>
<webHttpBinding>
<binding name="jsonBinding">
<security mode="None">
<transport clientCredentialType="None"/>
</security>
</binding>
</webHttpBinding>
</bindings>
</system.serviceModel>
</configuration>
Service.cs
protected override void OnStart(string[] args)
{
if (host != null) {
host.Close();
}
try
{
host = new ServiceHost(typeof(BestWebService.Service1));
host.Open();
}
catch (Exception e) {
string stored = #"c:\\SETUP ERROR.txt";
using (StreamWriter sw = File.AppendText(stored))
{
sw.WriteLine("1: {0}", e.ToString());
}
host.Close();
}
}
WCF Service Interface
public interface IService1
{
[OperationContract]
[WebInvoke(Method = "POST",
ResponseFormat = WebMessageFormat.Json,
RequestFormat =WebMessageFormat.Json)]
List<WKSTEnviornment> GetWKSTDetails();
}
Javascript
getAllVersions = function (id) {
$.ajax({
url: 'http://localhost/Service1.svc/GetWKSTDetails',
method: 'post',
contentType: 'application/json; charset=utf-8',
dataType: 'json',
success: function (data) {
var verlist = new Array();
var appname = new Array();
var applications = new Array();
var name = null;
var Object = {};
$.each(data.d, function (i) {
var apps = data.d[i]["AppList"].split('_');
verlist.push(data.d[i]["Version"]);
$.each(apps, function (i) {
appname.push(apps[i]);
})
appname.sort();
var ver = data.d[i]["Version"];
Object[ver] = { Date: data.d[i]["Date"], Applist: appname };
appname = [];
});
versionlist = Object;
getversion = true;
createDeployPanel(Object, verlist, id);
},
error: function (data) {
alert(JSON.stringify(data) + 'Get Versions Failed');
}
});
}
Thanks!!

I couldn't figure out the issue with Windows Service (the service is hosted successfully tho) so I switched it to IIS(config and CORS also took me some time to resolved), now it's working :)

Related

post of Uint8Array from angular javascript to wcf service is null when reaching service

Hi I'm trying to post a Uint8Array from angular javascript client to wcf service. The problem is that when
the array arrives at the service it is null. On the client end I've tried changing the array to different
types (int8, int16 etc..) and also not stringifying the data, but in all cases when it arrives at the
service it is null. On the service side I've tried to change the BodyStyle of the interface
from Wrapped to Bare, but got a 500 error. I've also made changes to web config parameters,
but I think web config is ok, because the post is actually making it to the method.
Any ideas what could be the problem? ultimately I'm trying to post an image from webcam on ipad or laptop
to wcf service for input into sql server. My code is below
Thanks
Pete
//ANGULAR post to WCF
const data = new Uint8Array(8);
data[0] = 26;
let body:any = JSON.stringify(data);// body = '{"0":26,"1":0,"2":0,"3":0,"4":0,"5":0,"6":0,"7":0}'
let headers = {'Access-Control-Allow-Credentials':'false',
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'DELETE, POST, GET, OPTIONS, PUT',
'Access-Control-Allow-Headers': 'application/json',
'Content-Type':'application/json'}
this.http.post(GlobalConstants.UploadServiceURL + "UploadPhotoDB", body, {'headers':headers}).subscribe(data => {
console.log(data);// null
})
WCF SERVICE
//Method
public byte[] UploadPhotoDB(byte[] input){//input is null
return input;
}
//Interface
[OperationContract(Name = "UploadPhotoDB")]
[DataContractFormat]
[WebInvoke(Method = "POST",
UriTemplate = "UploadPhotoDB/",
BodyStyle = WebMessageBodyStyle.Wrapped,
ResponseFormat = WebMessageFormat.Json,
RequestFormat = WebMessageFormat.Json
),
]
byte[] UploadPhotoDB(byte[] input);
//Applicable parts of WebConfig
<service name="SARIService.ServiceUpload" behaviorConfiguration="ServiceBehavior">
<endpoint address=""
binding="webHttpBinding"
bindingConfiguration="webHttpBindingConfig"
contract="SARIService.IServiceUpload"
behaviorConfiguration="web">
</endpoint>
</service>
<endpointBehaviors>
<behavior name="web">
<webHttp />
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="ServiceBehavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
<bindings>
<webHttpBinding>
<binding
maxBufferSize="999999" maxReceivedMessageSize="999999" />
<binding name="webHttpBindingConfig"
maxReceivedMessageSize="2147483647" maxBufferSize="2147483647" maxBufferPoolSize="2147483647" transferMode="Streamed" sendTimeout="00:05:00">
<!-- <security mode="Transport"/>-->
<readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647"/>
</binding>
</webHttpBinding>
</bindings>
On the angular javascript side I'm using ngx-webcam module to get the image. This has an imageAsBase64 property which stores the image as a base64 string. When I posted this string to the service and used FromBase64String on the c# wcf service to convert back to a byte array it worked.

XMLHttpRequest post 400 Bad request error when calling wcf Service

Hi I'm posting to a wcf service from javascript. I can post a single parameter (string, blob, int) fine, but when I try to put the data in a class I get a 400 Bad Request error. I've tried both Bare and Wrapped for my BodyStyle, but get the same error for each. Any ideas what could be happening?
Thanks
Pete
C# Data Contract:
[DataContract]
public class TestData
{
[DataMember]
public string SubmissionID { get; set; }
}
C# Interface:
[OperationContract(Name = "Upload")]
[DataContractFormat]
[WebInvoke(Method = "POST",
UriTemplate = "Upload/",
BodyStyle = WebMessageBodyStyle.Wrapped,//Bare gives same error
ResponseFormat = WebMessageFormat.Json)]
String Upload(TestData ps);
C# Service Method:
public String Upload(TestData ps)
{
....
return "Submission Complete";
}
Javascript call:
var TestData = {SubmissionID: "1" };
var xhr = new XMLHttpRequest();
xhr.open('POST', 'http://localhost:59070/WCFUploader.svc/Upload/', true);
xhr.send(TestData);//400 Bad Request
C# Web Config:
<?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="PhotoUploadServiceTest.WCFUploader" behaviorConfiguration="defaultServiceBehavior">
<endpoint address="" binding="webHttpBinding" behaviorConfiguration="defaultEndpointBehavior"
contract="PhotoUploadServiceTest.IWCFUploader" />
</service>
</services>
<bindings>
<webHttpBinding>
<binding maxBufferSize="2147483647"
maxBufferPoolSize="2147483647"
maxReceivedMessageSize="2147483647"
transferMode="Streamed"
sendTimeout="00:05:00">
<readerQuotas maxDepth="2147483647"
maxStringContentLength="2147483647"
maxArrayLength="2147483647"
maxBytesPerRead="2147483647"
maxNameTableCharCount="2147483647"/>
<security mode="None" />
</binding>
</webHttpBinding>
</bindings>
<behaviors>
<endpointBehaviors>
<behavior name="defaultEndpointBehavior">
<webHttp/>
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="defaultServiceBehavior">
<serviceMetadata httpGetEnabled="true" />
<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"/>
<!--
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>
The problem was in my javascript call. I needed to set the content of the request header to "application/json" and needed to create a String serial of the object before I sent it -- used dojo.toJson from the dojo library:
var TestData = {SubmissionID: "1" };
xhr.setRequestHeader("Content-type", "application/json");
var xhr = new XMLHttpRequest();
xhr.open('POST',
'http://localhost:59070/WCFUploader.svc/Upload/', true);
xhr.send(dojo.toJson(TestData));//this worked!!

Sending image in base64 to Webservice - 'application/octet-stream' was not the expected type 'text/xml; charset=utf-8'

I'm trying to save an html5 canvas content, to localhost by using a webserver.
I'm getting the canvas value in base64 and I send it to my webservice.
But when I send the data to the webservice I get this error and the file is not saved:
415: "Cannot process the message because the content type
'application/octet-stream' was not the expected type 'text/xml;
charset=utf-8'."
What am I doing wrong?
Service.vb
Imports System.IO
Imports System.Drawing
Public Class Service
Implements IService
Public Sub New()
End Sub
Public Function savePictureBase64(bytes As Byte()) As Boolean Implements IService.savePictureBase64
Dim fullOutputPath As String = "c:\temp\file.png"
'get a temp image from bytes, instead of loading from disk
'data:image/gif;base64,
Dim imagem As Image
Using ms As New MemoryStream(bytes)
imagem = Image.FromStream(ms)
End Using
File.WriteAllBytes(fullOutputPath, (bytes))
Return True
End Function
End Class
IService.vb
<ServiceContract()>
Public Interface IService
<OperationContract()>
Function savePictureBase64(bytes As Byte()) As Boolean
' TODO: Add your service operations here
End Interface
Javascript
function save () {
var image = document.getElementById("sketchpad").toDataURL("image/png");
image = image.replace('data:image/png;base64,', '');
$.ajax({
type: 'POST',
url: 'http://localhost:52193/service.svc',
data: image,
contentType: 'application/octet-stream',
success: function (msg) {
alert('Image saved successfully !');
},
error: function(result) {
alert("Error");
}
});
}
</script>
web.config
<?xml version="1.0"?>
<configuration>
<appSettings>
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true"/>
</appSettings>
<system.web>
<compilation debug="true" strict="false" explicit="true" targetFramework="4.5"/>
<httpRuntime targetFramework="4.5"/>
<pages>
<namespaces>
<add namespace="System.Runtime.Serialization"/>
<add namespace="System.ServiceModel"/>
<add namespace="System.ServiceModel.Web"/>
</namespaces>
</pages>
</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>
<bindings>
<basicHttpBinding>
<binding messageEncoding="Mtom">
</binding>
</basicHttpBinding>
</bindings>
<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>
The error is the call that you made by Javascript code. You try to send a string, the webservice expected an XML message:
expected type 'text/xml; charset=utf-8'.
I don't know how complicated it is to compose a webservice XML message from Javascript, but I think that you can change your approach. Your service is hosted under IIS, can you build an HttpHandler?
public class UploadBase64 : IHttpHandler
{
public bool IsReusable
{
get { return true; }
}
public void ProcessRequest(HttpContext context)
{
string image_string = string.Empty;
using (StreamReader sr = new StreamReader(context.Request.InputStream))
image_string = sr.ReadToEnd();
byte[] image_bin = Convert.FromBase64String(image_string);
File.WriteAllBytes(#"c:\temp_10\test01.png", image_bin);
}
}
...and add this to your web.config file:
<system.web>
<httpHandlers>
<add verb="POST" path="UploadBase64.aspx" type="WebApplication1.UploadBase64"/>
</httpHandlers>
</system.web>

Calling WCF Services with jQuery

I have 2 projects from which I need to call WCF services.
I have a problem calling services from one of them.
Therefore I made a simple service which is identical in both projects called Test1.
The SVC, ISVC and the Web.Config files are identical.
Any ideas what else can influance and be the reason why one project is working file and the other return a Bad request error.
I am working with Visual studio 2012.
Following is my code:
SVC file:
namespace Proj1.Web
{
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class Proj1SVC : IProj1SVC
{
public string Test1()
{
return "Project 1";
}
}
}
ISVC file:
namespace Proj1.Web
{
[ServiceContract]
public interface IProj1SVC
{
[OperationContract]
string Test1();
}
}
Web.Config file:
<?xml version="1.0"?>
<!--
For more information on how to configure your ASP.NET application, please visit
http://go.microsoft.com/fwlink/?LinkId=169433
-->
<configuration>
<connectionStrings>
<add name="Proj1dbConnectionString" connectionString="Data Source=Proj1Comp\SQLEXPRESS;Initial Catalog=Proj1dbKK;Integrated Security=True"
providerName="System.Data.SqlClient" />
</connectionStrings>
<system.web>
<roleManager enabled="true"/>
<compilation debug="true" targetFramework="4.0">
</compilation>
<!--
The <authentication> section enables configuration
of the security authentication mode used by
ASP.NET to identify an incoming user.
-->
<!-- <authentication mode="Windows"/> -->
<authentication mode="Forms">
<!-- The name, protection, and path attributes must match
exactly in each Web.config file. -->
<forms loginUrl="login.aspx" name=".ASPXFORMSAUTH" protection="All" path="/" domain="kk.Proj1.com" timeout="600"/>
</authentication>
<!-- Validation and decryption keys must exactly match and cannot
be set to "AutoGenerate". The validation and decryption
algorithms must also be the same. -->
<machineKey validationKey="SomeValidationKeyInHex" decryptionKey="SomeDecryptionKeyInHex" validation="SAA1"/>
<authorization>
<allow roles="administrators"/>
<allow users="?" />
</authorization>
<!--
The <customErrors> section enables configuration
of what to do if/when an unhandled error occurs
during the execution of a request. Specifically,
it enables developers to configure html error pages
to be displayed in place of a error stack trace.
<customErrors mode="RemoteOnly" defaultRedirect="GenericErrorPage.htm">
<error statusCode="403" redirect="NoAccess.htm" />
<error statusCode="404" redirect="FileNotFound.htm" />
</customErrors>
-->
<pages controlRenderingCompatibilityVersion="3.5" clientIDMode="AutoID"/>
</system.web>
<!-- Added for server side authentication data to be available in the WCF service -->
<!-- STX -->
<system.web.extensions>
<scripting>
<webServices>
<authenticationService enabled="true" requireSSL="false"/>
</webServices>
</scripting>
</system.web.extensions>
<!-- ETX -->
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" aspNetCompatibilityEnabled="true"/>
<diagnostics>
<messageLogging
logEntireMessage="true"
logMalformedMessages="false"
logMessagesAtServiceLevel="true"
logMessagesAtTransportLevel="false"
maxMessagesToLog="3000"
maxSizeOfMessageToLog="2000"/>
</diagnostics>
</system.serviceModel>
</configuration>
you need to specify attributes at operation level in the service contract file for each method or operation. To do this, decorate the method with WebInvoke, which marks a service operation as one that responds to HTTP requests other than GET. Accordingly, your operational level code in the contract file will be as follows:
[OperationContract]
[WebInvoke(Method = "POST",
BodyStyle = WebMessageBodyStyle.Wrapped,
ResponseFormat = WebMessageFormat.Json)]
string Test1(string Id);
You need to change the default configuration created by Visual Studio in Web.Config file for WCF services, so that it works with the HTTP protocol request send by jQuery client code.
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="ServiceBehavior">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="EndpBehavior">
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
<services>
<service behaviorConfiguration="ServiceBehavior" name="Service">
<endpoint address="" binding="webHttpBinding"
contract="IService" behaviorConfiguration="EndpBehavior"/>
</service>
</services>
</system.serviceModel>
Call ur service using jQuery.ajax()
function CallService() {
$.ajax({
type: Type, //GET or POST or PUT or DELETE verb
url: Url, // Location of the service
data: Data, //Data sent to server
contentType: ContentType, // content type sent to server
dataType: DataType, //Expected data format from server
processdata: ProcessData, //True or False
success: function(msg) {//On Successfull service call
ServiceSucceeded(msg);
},
error: ServiceFailed// When Service call fails
});
}
function ServiceFailed(result) {
alert('Service call failed: ' + result.status + '' + result.statusText);
Type = null;
varUrl = null;
Data = null;
ContentType = null;
DataType = null;
ProcessData = null;
}

How to Call Websocket from HTML Client?

I have written one wcf Service with netHttpBinding binding and hosted in II8(windows server 2012).The interfaces are like the bellow.
[ServiceContract(CallbackContract = typeof(IDuplexCallbackContract))]
public interface IHelloWebSocket
{
[OperationContract(IsOneWay = true, Action = "*")]
void SayHelloDuplexReceive(string name);
}
[ServiceContract]
public interface IDuplexCallbackContract
{
[OperationContract(IsOneWay = true, Action = "*")]
void SayingHelloSend(string message);
}
now I have the service class implementation like the bellow..
[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Reentrant)]
public class HelloWebSocket : IHelloWebSocket
{
/// <summary>
/// Call back instance called from service to client.
/// </summary>
IDuplexCallbackContract _callback = null;
public HelloWebSocket()
{
_callback =
OperationContext.Current.GetCallbackChannel<IDuplexCallbackContract>();
}
public void SayHelloDuplexReceive(string name)
{
_callback.SayingHelloSend("Hello " + name + " by WebSockets");
//return "Hello " + name;
}
}
and the web config like the bellow..
<system.serviceModel>
<services>
<service name="WebSocketUndersranding.HelloWebSocket">
<endpoint address=""
binding="netHttpBinding"
contract="WebSocketUndersranding.IHelloWebSocket"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true"
multipleSiteBindingsEnabled="true" />
</system.serviceModel>
Now How Can I call the Service from the HTML5 client.??
My Service URL is a link
I am trying to write the client
var websocket = new WebSocket(uri);
but what should I put in the "uri" to call the service.I am not able to get..???
Thanks,
Arijit
You can use this articles as example to start from:
http://www.codeproject.com/Articles/338789/What-s-new-in-WCF-4-5-WebSocket-support-Part-1-of
http://www.codeproject.com/Articles/341413/What-s-new-in-WCF-4-5-WebSocket-support-Part-2-of

Categories

Resources