将文件从silverlight上传到WCF服务

时间:2010-10-21 14:36:46

标签: c# .net silverlight wcf

我无法将(从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;
}

2 个答案:

答案 0 :(得分:0)

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

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

答案 1 :(得分:0)

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

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