In my web project I have a TestStreamingService.svc file containing a REST service.
The service contract :
[ServiceContract(Namespace = "")]
public interface ITestStreamingService
{
[OperationContract]
[WebGet(UriTemplate = "Download?file={file}&size={size}")] //file irrelevant, size = returned size of the download
Stream Download(string file, long size);
[OperationContract]
[WebInvoke(UriTemplate= "Upload?file={file}&size={size}", Method = "POST")]
void Upload(string file, long size, Stream fileContent);
[OperationContract(AsyncPattern=true)]
[WebInvoke(UriTemplate = "BeginAsyncUpload?file={file}", Method = "POST")]
IAsyncResult BeginAsyncUpload(string file, Stream data, AsyncCallback callback, object asyncState);
void EndAsyncUpload(IAsyncResult ar);
}
The service implementation (the *.svc file)
using System; using System.IO; using System.ServiceModel; using System.ServiceModel.Activation; using ICode.SHF.Tests;
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)] [ServiceBehavior(InstanceContextMode=InstanceContextMode.Single)] public class TestStreamingService : ITestStreamingService {
public Stream Download(string file, long size)
{
return new SHFTestStream(size);
}
public void Upload(string file, long size, Stream fileContent)
{
FileInfo f = new FileInfo(String.Format(@"C:\{0}", file));
using (FileStream fs = f.Create())
{
CopyStream(fileContent, fs);
fs.Flush();
fs.Close();
}
}
public IAsyncResult BeginAsyncUpload(string file, Stream data, AsyncCallback callback, object asyncState)
{
return new CompletedAsyncResult<Stream>(data, file);
}
public void EndAsyncUpload(IAsyncResult ar)
{
Stream data = ((CompletedAsyncResult<Stream>)ar).Data;
string file = ((CompletedAsyncResult<Stream>)ar).File;
StreamToFile(data, file);
}
private void StreamToFile(Stream data, string file)
{
string subDir = Guid.NewGuid().ToString("N");
string uploadDir = Path.Combine(Path.GetDirectoryName(typeof(TestStreamingService).Assembly.Location), subDir);
Directory.CreateDirectory(uploadDir);
byte[] buff = new byte[0x10000];
using (FileStream fs = new FileStream(Path.Combine(uploadDir, file), FileMode.Create))
{
int bytesRead = data.Read(buff, 0, buff.Length);
while (bytesRead > 0)
{
fs.Write(buff, 0, bytesRead);
bytesRead = data.Read(buff, 0, buff.Length);
}
}
}
}
public class CompletedAsyncResult : IAsyncResult { T data;
string file;
public CompletedAsyncResult(T data, string file)
{ this.data = data; this.file = file; }
public T Data
{ get { return data; } }
public string File
{ get { return file; } }
#region IAsyncResult Members
public object AsyncState
{
get { return (object)data; }
}
public System.Threading.WaitHandle AsyncWaitHandle
{
get { throw new NotImplementedException(); }
}
public bool CompletedSynchronously
{
get { return true; }
}
public bool IsCompleted
{
get { return true; }
}
#endregion
}
My Web.Config
<?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>
<system.web>
<compilation debug="true" targetFramework="4.0" />
</system.web>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="REST">
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
<bindings>
<webHttpBinding>
<binding name="ICode.SHF.SL.Tests.Web.TestStreamingService.customBinding0"/>
</webHttpBinding>
</bindings>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true"
/>
<services>
<service name="ICode.SHF.SL.Tests.Web.TestStreamingService">
<host>
<baseAddresses>
<add baseAddress="http://localhost:40000/Streaming"/>
</baseAddresses>
</host>
<endpoint name="TestStreamingEndpoint" address="RESTService" binding="webHttpBinding" bindingConfiguration="ICode.SHF.SL.Tests.Web.TestStreamingService.customBinding0"
contract="ICode.SHF.SL.Tests.Web.ITestStreamingService" behaviorConfiguration="REST"/>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
</services>
</system.serviceModel>
</configuration>
I'm trying to consume the service from silverlight (the web project contains a clientaccesspolicy.xml) via a WebClient however I seem to fail, Fiddler doesn't show any calls being made.
(using WebClient.OpenWriteAsync (for upload) & OpenReadAsync (for download))
The uri used for the Client is : "http://localhost:40000/Streaming/Service/Download?file=xxx&size=65536"
When I use the following uri in IE : "http://localhost:40000/TestStreamingService.svc/Download?file=xxx&size=65536" a download operation begins and the downloaded file matches the size passed.
I'm not having success with the IE uri in the WebClient though.
Could anyone please explain to me what am I doing wrong? It seems I've missed something fundamental...