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