从Silverlight使用REST服务时出现问题

时间:2011-01-21 14:21:07

标签: c# silverlight wcf rest

在我的Web项目中,我有一个包含REST服务的TestStreamingService.svc文件。

服务合同:

[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);

    } 

服务实现(* .svc文件)

使用System; 使用System.IO; 使用System.ServiceModel; 使用System.ServiceModel.Activation; 使用ICode.SHF.Tests;

[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)] [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)] 公共类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数据;

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

}

我的网站.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>

我正在尝试通过WebClient从silverlight(web项目包含clientaccesspolicy.xml)中使用该服务,但是我似乎失败了,Fiddler没有显示任何调用。

(使用WebClient.OpenWriteAsync(用于上传)和OpenReadAsync(用于下载))

用于客户端的uri是:“http:// localhost:40000 / Streaming / Service / Download?file = xxx&amp; size = 65536”

当我在IE中使用以下uri时:“http:// localhost:40000 / TestStreamingService.svc / Download?file = xxx&amp; size = 65536”下载操作开始,下载的文件与传递的大小相匹配。

我在WebClient中没有成功使用IE uri。

有人可以向我解释我做错了什么吗?我似乎错过了一些基本的东西......

2 个答案:

答案 0 :(得分:0)

您的网站是否需要身份验证?至于提琴手,请尝试将您的网络客户端连接到:

http://localhost.:40000/Streaming/Service/Download?file=xxx&size=65536

(注意localhost之后的额外点数)

答案 1 :(得分:0)

似乎我已经设法通过Silverlight解决了有关下载功能的问题。 Web客户端。

这就是我的所作所为。

  1. 将服务合同和实施移至单独的项目MyWCFLibrary(WCF服务库)
  2. 将所述库的引用添加到托管项目的ASP.NET网站
  3. 添加了一个文本文件“Service.svc”并对其进行了编辑:

    &lt;%@ ServiceHost Language =“C#”Debug =“true”Service =“MyWCFLibrary.TestStreamingService”Factory =“System.ServiceModel.Activation.WebServiceHostFactory”%&gt;

  4. 修改了WebClient操作的uri以匹配* .svc文件

  5. 似乎有效。

    我仍在尝试解决一件事,所以欢迎提出意见:

    我可以通过Webclient对服务执行操作,如下所示:

    WebClient wc = new WebClient();
     string uri = String.Format("http://localhost.:40000/Service.svc/Download?file=xxx&size={0}", size);
                    wc.OpenReadAsync(new Uri(uri));
    

    但不是这样的:

     string uri = String.Format("http://localhost.:40000/Services/StreamingService/Download?file=xxx&size={0}", size);
                    wc.OpenReadAsync(new Uri(uri));
    

    其中:localhost:40000 / Services是服务的基地址,StreamingService是端点的地址(我的WebConfig中的最新更改)

    任何人都可以解释原因吗?还是我坚持使用默认的第一个uri?