开发者

Uploading file from silverlight to WCF service

I am having trouble to upload(from Silverlight 4) a wav file to the server(WCF .NET 4). The file is uploaded from SL to server and write it to disk. But the uploaded file is changed. The two files(before uploading and the uploaded one) have exact same size but different content. And I tried the uploading in a normal console program, it works fine. It seems that the WCF has done something when serializing the data from SL. Anyone has any ideas what is going on ?

The service code is as following:

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

Service config is

<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 client is:

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


I found the problem. It has nothing to do with WCF or SL. The problem is about IO, stream.

In the SL app, the stream position was not at 0 because it was manipulated before. So it works when the position is changed back to 0 before calling stream.Read(...). But I am still wondering why it was still able to read the whole stream even the position was not at 0 before(even I set the length to (int)stream.Length). Maybe when it gets to the end of the stream, it turns back to read from the beginning again ?


if Stream.Read cannot read enough bytes, it will simply not fill the remaining bytes in your buffer, leaving them on their initial value "changing" your file... Read() returns the number of bytes actually read, so cou could do the following to ensure you got all bytes: but of course your self-answer will fix your problem, nevertheless some hints for followers...

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜