【问题标题】:Uploading file from silverlight to WCF service将文件从 silverlight 上传到 WCF 服务
【发布时间】:2010-10-21 14:36:46
【问题描述】:

我无法(从 Silverlight 4)上传 wav 文件到服务器(WCF .NET 4)。该文件从 SL 上传到服务器并将其写入磁盘。但是上传的文件被改变了。这两个文件(上传前和上传的文件)大小完全相同,但内容不同。我尝试在普通控制台程序中上传,效果很好。从 SL 序列化数据时,WCF 似乎做了一些事情。有人知道发生了什么吗?

服务代码如下:

[ServiceContract(Namespace = "")]
interface ISoundService
{
    [OperationContract]
    int UploadSound(UploadSoundFile file);
}

public int UploadSound(UploadSoundFile file)
{
    var path = Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + "/" + file.FileName;
    File.WriteAllBytes(path, file.File);
    return 0;
}

[DataContract]
public class UploadSoundFile
{
    [DataMember]
    public string FileName;

    [DataMember]
    public byte[] File;
}

服务配置是

<system.serviceModel>
    <bindings>
        <basicHttpBinding>
            <binding name="Service.SoundService.customBinding0" maxReceivedMessageSize="2000000" maxBufferSize="2000000">
                <readerQuotas maxArrayLength="2000000" maxStringContentLength="2000000"/>
            </binding>
        </basicHttpBinding>
    </bindings>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>
    <services>
        <service behaviorConfiguration="Service.SoundServiceBehavior" name="Service.SoundService">
            <endpoint address="" binding="basicHttpBinding" contract="Service.ISoundService" bindingConfiguration="Service.SoundService.customBinding0"/>
            <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
        </service>
    </services>
    <behaviors>
        <serviceBehaviors>
            <behavior name="Service.SoundServiceBehavior">
                <serviceMetadata httpGetEnabled="true"/>
                <serviceDebug includeExceptionDetailInFaults="true"/>
            </behavior>
        </serviceBehaviors>
    </behaviors>
</system.serviceModel>

Silverlight 客户端是:

private static int uploadSoundOnServer(string fileName, Stream stream)
{
    SoundServiceClient c = new SoundServiceClient();
    byte[] buffer = new byte[stream.Length];
    stream.Read(buffer, 0, checked((int)stream.Length));
    UploadSoundFile file = new UploadSoundFile() { FileName= fileName, File = buffer, };
    c.UploadSoundAsync(file);
    return 0;
}

【问题讨论】:

  • - 文件是通过什么方式改变的?
  • 另外,你能不能用一个小文件(大概 10 字节左右)试试,然后用 Fiddler 看一下线路,看看发生了什么?
  • 嗨,尤金,谢谢。它帮助我调查问题。我发现了问题。

标签: c# .net silverlight wcf


【解决方案1】:

我发现了问题。它与 WCF 或 SL 无关。问题在于 IO、流。

在 SL 应用程序中,流位置不是 0,因为它之前被操纵过。因此,在调用 stream.Read(...) 之前将位置更改回 0 时它可以工作。但是我仍然想知道为什么即使位置之前不是0它仍然能够读取整个流(即使我将长度设置为(int)stream.Length)。也许当它到达流的末尾时,它会再次从头开始读取?

【讨论】:

    【解决方案2】:

    如果 Stream.Read 无法读取足够的字节,它将根本不会填充缓冲区中的剩余字节,而将它们保留为初始值“更改”您的文件... Read() 返回实际读取的字节数,因此可以执行以下操作以确保获得所有字节: 但当然你的自我回答会解决你的问题,不过给关注者一些提示......

    private static int uploadSoundOnServer(string fileName, Stream stream)
    {
        SoundServiceClient c = new SoundServiceClient();
        /* Ensure we read from the start again */
        stream.Seek(0, SeekOrigin.Begin);
        int expectedBytes = stream.Length;
        byte[] buffer = new byte[expectedBytes];
        int bytesRead = stream.Read(buffer, 0, checked((int)expectedBytes));
        /* check read bytes count to match expected stream length */
        if (bytesRead < expectedBytes)
        {
            throw new BadBugException("I missed some bytes");
        }
        UploadSoundFile file = new UploadSoundFile() { FileName = fileName, File = buffer, };
        c.UploadSoundAsync(file);
        //TODO: stream.Seek(oldPosition); for the caller
        return 0;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-10-04
      • 2011-11-12
      • 2010-09-08
      • 2012-02-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多