access wcf self service host using js - javascript

I created a wcf self service host
I can access it , and see it's wsdl
but when trying to add the /js extension to the path I get 405 error.
I cannot understand why, while doing the same with a asp.net web applicaton it worked ok.
wcf class :
namespace A
{
[ServiceBehavior(IncludeExceptionDetailInFaults=true)]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class Hello : IHello
{
public string SayHi()
{
return "Hiush !";
}
}
}
wcf interface:
namespace A
{
[ServiceContract]
public interface IHello
{
[OperationContract]
string SayHi();
}
}
wcf svc file:
<%# ServiceHost Language="C#" Debug="true" Service="A.Hello" %>
the self service host:
namespace SelfServiceHost
{
class Program
{
static void Main(string[] args)
{
using (ServiceHost helloHost = new ServiceHost(typeof(A.Hello)))
{
helloHost.Open();
Console.WriteLine("HelloHost started # " + DateTime.Now);
Console.ReadKey();
}
}
}
}
self service host app.config:
<?xml version="1.0"?>
<configuration>
<system.web>
<compilation debug="true"/>
</system.web>
<!-- When deploying the service library project, the content of the config file must be added to the host's
app.config file. System.Configuration does not support config files for libraries. -->
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="" closeTimeout="00:01:00"
openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
allowCookies="false" bypassProxyOnLocal="true" hostNameComparisonMode="StrongWildcard"
maxBufferSize="524288" maxBufferPoolSize="524288" maxReceivedMessageSize="524288"
messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
useDefaultWebProxy="true">
<readerQuotas maxDepth="32" maxStringContentLength="524288" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<!--<security mode="TransportCredentialOnly">
<transport clientCredentialType="Windows" proxyCredentialType="None"
realm="" />
<message clientCredentialType="UserName" algorithmSuite="Default" />
</security>-->
</binding>
</basicHttpBinding>
</bindings>
<services>
<service name="A.Hello">
<endpoint address="PINCalc" behaviorConfiguration="AAA"
binding="webHttpBinding" contract="A.IHello">
<!--<identity>
<dns value="localhost"/>
</identity>-->
</endpoint>
<host>
<baseAddresses>
<add baseAddress="http://localhost:3020/Hello.svc"/>
</baseAddresses>
</host>
<!-- Service Endpoints -->
<!-- Unless fully qualified, address is relative to base address supplied above -->
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="True"/>
<serviceDebug includeExceptionDetailInFaults="True"/>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="AAA">
<enableWebScript/>
</behavior>
</endpointBehaviors>
</behaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true"/>
</system.serviceModel>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/></startup></configuration>

Related

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>

Get a file from server using wcf and download at clients browser

I am having a WCF service to read file content and i am calling it on my webpage using JavaScript and getting the content as response.
Now what i have to do is instead of reading its content i have to download this file from server to the client system,any idea how to do get a file from server using wcf ?
WCF:-
public Stream getFileFromPath(string filepath)
{
String[] filename=filepath.Split('\\');
WebOperationContext.Current.OutgoingResponse.ContentType = "application/octet-stream";
if(File.Exists(filepath)
{
String headerInfo = "attachment; filename=" + filename[filename.Length - 1];
WebOperationContext.Current.OutgoingResponse.Headers["Content-Disposition"] = headerInfo;
return File.OpenRead(filepath);
}
else
{
String headerInfo = "attachment; filename=" + "error.txt";
WebOperationContext.Current.OutgoingResponse.Headers["Content-Disposition"] = headerInfo;
string errortext="file not found";
byte[] byteArray = Encoding.ASCII.GetBytes(errortext);
MemoryStream stream = new MemoryStream(byteArray);
return stream;
}
}
web.config:-
<system.serviceModel>
<bindings>
<webHttpBinding>
<binding name="MyWcfRestService.WebHttp" 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>
<services>
<service behaviorConfiguration="MyWcfRestService.FileUploadServBehavior" name="MyWcfRestService.FileUploadServ">
<endpoint address="" behaviorConfiguration="web" binding="webHttpBinding" bindingConfiguration="MyWcfRestService.WebHttp" contract="MyWcfRestService.IFileUploadServ">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
</services>
<behaviors>
<endpointBehaviors>
<behavior name="web">
<webHttp helpEnabled=”true”/>
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="MyWcfRestService.FileUploadServBehavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
JavaScript:-
function downloadfile(filepath)
{
var url="https://abc/service.svc/getfilestream?v="+filepath;
window.open(url,"windowname","width:400,height:300");
}

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