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

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");
}

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!!

WCF endpoint not found/method not allowed using Windows Service

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 :)

Getting HTTPS 405 method not allowed when calling REST Service

I am trying to hit an HTTPS REST SERVICE hosted on Windows Server from a website hosted on Unix Server but I am getting 405 Method Not Allowed error.
Exception I am getting on browser console is::
OPTIONS
https://auth.syrasoft.com/10.0.0.101/authservice.svc/rest/r_PerformLogin
XMLHttpRequest cannot load
https://auth.syrasoft.com/10.0.0.101/authservice.svc/rest/r_PerformLogin.
Response for preflight has invalid HTTP status code 405
My Client Code which is trying to access REST service is:
createCORSRequest: function(method, url) {
var xhr = new XMLHttpRequest();
if ("withCredentials" in xhr) {
// Most browsers.
xhr.open(method, url, true);
} else if (typeof XDomainRequest != "undefined") {
// IE8 & IE9
xhr = new XDomainRequest();
xhr.open(method, url);
} else {
// CORS not supported.
xhr = null;
}
return xhr;
},
doSignIn: function(event) {
console.log('inside sign in');
event.preventDefault();
$('#ErrMsg').hide(); // Hide any errors on a new submit
console.log('Logging in... ');
var url = 'https://auth.syrasoft.com/10.0.0.101/authservice.svc/rest/r_PerformLogin';
var method = 'POST';
var formValues = {
AccountID: 28462,
CurrentVersion: "10.0.0.103",
GoogleRedirect: null,
GoogleToken: null,
GroupID: 0,
Method: 2,
PC_Name: "DEV7",
Password: [97, 136, 201, 199, 60, 1, 89, 216, 184, 191, 82, 1, 114, 252, 127, 16, 0, 184, 64, 9, 82, 84, 81, 147, 12, 83, 100, 38, 197, 209, 252, 151],
Source: 0,
UserName: "mikeo"
};
var xhr = this.createCORSRequest(method, url);
xhr.setRequestHeader("Content-Type","application/json");
xhr.setRequestHeader("X-Requested-With","XMLHttpRequest");
xhr.setRequestHeader("Accept","application/json");
xhr.onload = function() {
console.log('success');
var data = xhr.responseText;
if (data) {
var json = jQuery.parseJSON(data);
console.log(json);
app.navigate("home", {
trigger: true
});
}
};
xhr.onerror = function() {
console.log('error');
var data = xhr.responseText;
if (data) {
var json = jQuery.parseJSON(data);
$('#ErrMsg').text(json.error.text).show();
}
};
xhr.send(JSON.stringify(formValues));
}
Configuration on REST Server side is:
<?xml version="1.0"?>
<configuration>
<appSettings>
<add key="EnableDebugLogging" value="true" />
<add key="LogFileName" value="AuthenticationService.txt" />
</appSettings>
<system.web>
<customErrors mode="Off"/>
<compilation strict="false" explicit="true" targetFramework="4.0">
<assemblies>
<add assembly="MySql.Data, Version=6.9.5.0, Culture=neutral, PublicKeyToken=C5687FC88969C44D" />
</assemblies>
</compilation>
<pages>
<namespaces>
<add namespace="System.Runtime.Serialization" />
<add namespace="System.ServiceModel" />
<add namespace="System.ServiceModel.Web" />
</namespaces>
</pages>
</system.web>
<system.serviceModel>
<client>
<endpoint address="http://localhost:64331/AutoUpdate.svc" binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IVersionCheck" contract="AutoUpdateService.IVersionCheck" name="BasicHttpBinding_IVersionCheck" />
</client>
<services>
<service name="AuthenticationService">
<endpoint address="" binding="wsHttpBinding" name="wb" contract="IAuthenticationService" bindingConfiguration="wb">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint name="restful" address="rest" binding="webHttpBinding" contract="IRESTfulAuth" bindingConfiguration="bw" behaviorConfiguration="web"/>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://localhost/" />
</baseAddresses>
</host>
</service>
</services>
<!--Binding Settings-->
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_IVersionCheck" />
</basicHttpBinding>
<wsHttpBinding>
<binding name="wb" closeTimeout="00:10:00" openTimeout="00:10:00" receiveTimeout="00:10:00" sendTimeout="00:10:00">
<security mode="Transport">
<transport clientCredentialType="None" />
</security>
</binding>
</wsHttpBinding>
<webHttpBinding>
<binding name="bw" receiveTimeout="00:10:00" sendTimeout="00:10:00" openTimeout="00:10:00" closeTimeout="00:10:00">
<security mode="Transport">
<transport clientCredentialType="None" proxyCredentialType="None" realm=""/>
</security>
</binding>
</webHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="web">
<webHttp />
</behavior>
</endpointBehaviors>
</behaviors>
<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="false" />
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Headers" value="Content-Type,Accept,X-Requested-With" />
<add name="Access-Control-Allow-Origin" value="http://syrasoftconnect.com" />
<add name="Access-Control-Allow-Methods" value="POST,GET,OPTIONS,PUT,DELETE" />
</customHeaders>
</httpProtocol>
</system.webServer>
</configuration>
The thing here is when I mock the REST Service through SOAP UI, I am perfectly able to call it from the website but not when it is hosted on the Windows Server. I believe there could be some problem with the server configuration but I am not able to pin point it. I have tried almost all the solutions available on stackoverflow related to the same issue but no luck.
Do you guys see anything wrong in my code or server configuration?

access wcf self service host using js

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>

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