简体   繁体   中英

Error when accessing WCF Service with Byte parameter in Silverlight Application

I am developing a test application where I can upload images to Web Server using Silver-light application.

Following is the code of my WCF SERVICE:

Code of IImageService.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using System.ServiceModel;
using System.Reflection;

// NOTE: You can use the "Rename" command on the "Refactor" menu to change the interface name "IImageService" in both code and config file together.
[ServiceKnownType("GetKnownTypes", typeof(Helper))]
[ServiceContract]
public interface IImageService
{
    [OperationContract]
    int DoSum(int a, int b);


    [OperationContract]
    ResultInfo UploadPhoto(FileInfo fileInfo);

    [OperationContract]
    void UploadPhoto2(FileInfo fileInfo);

    [OperationContract]
    void UploadPhoto3(byte[] byteInfo);
}

// This class has the method named GetKnownTypes that returns a generic IEnumerable. 
static class Helper
{
    public static IEnumerable<Type> GetKnownTypes(ICustomAttributeProvider provider)
    {
        System.Collections.Generic.List<System.Type> knownTypes =
            new System.Collections.Generic.List<System.Type>();
        // Add any types to include here.
        knownTypes.Add(typeof(FileInfo));
        knownTypes.Add(typeof(ResultInfo));
        return knownTypes;
    }
}

Code of ImageService.cs

    using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;

// NOTE: You can use the "Rename" command on the "Refactor" menu to change the class name "ImageService" in code, svc and config file together.
public class ImageService : IImageService
{
    public int DoSum(int a, int b)
    {
        return a + b;
    }

    public ResultInfo UploadPhoto(FileInfo fileInfo)
    {
        ResultInfo strResult = new ResultInfo();
        try
        {
            if (fileInfo.Mode == "StaffImage")
            {
                if (fileInfo.ID.HasValue)
                {
                    strResult.Result = "Staff image will be uploaded";
                }
            }
        }
        catch{}
        return strResult;
    }


    public void UploadPhoto2(FileInfo fileInfo)
    {
        ResultInfo strResult = new ResultInfo();
        try
        {
            if (fileInfo.Mode == "StaffImage")
            {
                if (fileInfo.ID.HasValue)
                {
                    strResult.Result = "Staff image will be uploaded";
                }
            }
        }
        catch { }
    }

    public void UploadPhoto3(byte[] byteInfo)
    {

    }
}

[MessageContract]
public class FileInfo
{
    [MessageBodyMember(Order = 1)]
    public string FileName;

    [MessageBodyMember(Order = 2)]
    public string Mode;

    [MessageBodyMember(Order = 3)]
    public long? ID;

    [MessageBodyMember(Order = 4)]
    public Byte[] FileByte;
}

[MessageContract]
public class ResultInfo
{
    [DataMember]
    public string Result;
}

Code of web.cofig

  <configuration>
<appSettings>
  <add key="PictureUploadDirectory" value="/UploadDocs"/>
</appSettings>
  <system.web>
    <compilation debug="true" targetFramework="4.0">
  </compilation>    
</system.web>

  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true">
      <add name="UrlRoutingModule" type="System.Web.Routing.UrlRoutingModule, System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
    </modules>
  </system.webServer>

<system.serviceModel>

  <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
  <services>
    <service name="MyService">
      <endpoint address="" binding="webHttpBinding" contract="IImageService" behaviorConfiguration="web"/>
      <endpoint address="" binding="mexHttpBinding" contract="IImageService" behaviorConfiguration="MEX"/>
    </service>
  </services>
  <bindings>
    <webHttpBinding>
      <binding maxReceivedMessageSize="2097152" maxBufferSize="2097152"

             maxBufferPoolSize="2097152"
             transferMode="Buffered"
             bypassProxyOnLocal="false"
             useDefaultWebProxy="true"

               />
    </webHttpBinding>
  </bindings>
  <behaviors>
    <serviceBehaviors>
      <behavior name="MEX">
        <serviceMetadata />
      </behavior>
      <behavior name="">
        <serviceMetadata httpGetEnabled="true" />
        <serviceDebug includeExceptionDetailInFaults="false" />
      </behavior>
    </serviceBehaviors>
    <endpointBehaviors>
      <behavior name="web">
        <webHttp />
      </behavior>
      <behavior name="MEX">
        <webHttp/>
      </behavior>
    </endpointBehaviors>
  </behaviors>
</system.serviceModel>

Code in Silverlight application

  ServiceReference1.ImageServiceClient objImgServiceClient = new    ServiceReference1.ImageServiceClient();
                objImgServiceClient.DoSumCompleted += objImgServiceClient_DoSumCompleted;
                ServiceReference1.DoSumRequest req1 = new ServiceReference1.DoSumRequest();
                req1.a = 2;
                req1.b = 3;
                objImgServiceClient.DoSumAsync(req1);
                FileInfo _Info=new FileInfo();
                _Info.FileName = "Test_File.jpg";
                _Info.Mode = "StaffImage";
                _Info.ID = 25;
                _Info.FileByte = fileToSend;
                objImgServiceClient.UploadPhotoCompleted += objImgServiceClient_UploadPhotoCompleted;
                //objImgServiceClient.UploadPhotoAsync(_Info.FileName, _Info.Mode, _Info.ID, _Info.FileByte);
                ServiceReference1.FileInfo objF = new ServiceReference1.FileInfo();
                objF.FileByte = _Info.FileByte;
                objF.Mode = _Info.Mode;
                objF.ID = _Info.ID;
                objF.FileName = _Info.FileName;
                objImgServiceClient.UploadPhotoAsync(objF);

Error detail

When I access the DoSum() Method it returns the correct result. But when I try to call any method with Stream/Byte parameter then I get following error:

[System.ServiceModel.CommunicationException] = {System.ServiceModel.CommunicationException: The remote server returned an error: NotFound. ---> System.Net.WebException: The remote server returned an error: NotFound. ---> System.Net.WebException: The remote server returned an error: NotFound. at Syst...

EDIT:------------------

When I change the Byte[] to string then it works perfectly, I am having problem with byte[] datatype as I need Stream/byte[] to upload image to server. Any Ideas?

[MessageContract]
public class FileInfo
{
[MessageBodyMember(Order = 1)]
public string FileName;

[MessageBodyMember(Order = 2)]
public string Mode;

[MessageBodyMember(Order = 3)]
public long? ID;

[MessageBodyMember(Order = 4)]
/*public Byte[] FileByte;*/
 public string FileByte;
}

Edit: 2---------------------

Please check the following Screen shots, I can't set the maxReceivedMessageSize to WCF Service, if Stream content is small it's get to the Server, but not large.

这是请求正文这是回应机构

Thanks

The error message doesn't say much to me. Try turning on WCF tracing . Very simple to configure but is a great tool for troubleshooting WCF issues. This usually provides you with more specific and friendly error messages.

Hope it helps!

Specify address:

<services>
<service name="ImageService ">
  <endpoint address="imageservice" binding="webHttpBinding" contract="IImageService" behaviorConfiguration="web"/>
  <endpoint address="mex" binding="mexHttpBinding" contract="IImageService" behaviorConfiguration="MEX"/>

  <host>
    <baseAddresses>
      <add baseAddress="http://localhost/"/>
    </baseAddresses>
  </host>
</service>

Address for your client to use is:

http://{MachineName}/imageservice

In case you host you app on IIS, you need to have svc file. And try to understand if you service start. Enable tracing for that or set up error handling: Error handling for WCF service

EDIT 1:

I've just notice that you don't use namespace - it's really bad practice.

EDIT 2:

  1. Try to avoid using Order property for MessageContract and DataContract, it's not good practice.
  2. You should not use Message Contract as there is no reason to use it for your case. Data contract for you should be:

     [DataContract] public class FileInfo { [DataMember] public string FileName; [DataMember] public string Mode; [DataMember] public long? ID; [DataMember] public byte[] FileByte; } [DataContract] public class ResultInfo { [DataMember] public string Result; } 
  3. There is no need to use "[ServiceKnownType("GetKnownTypes", typeof(Helper))]" for you.

  4. As you use WebHttpBinding you have to apply WebGet, WebInvoke attributes:

     [ServiceContract] public interface IImageService { [OperationContract] [WebInvoke(Method = "POST", UriTemplate = "photos", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)] ResultInfo UploadPhoto(FileInfo fileInfo); [WebInvoke(Method = "POST", UriTemplate = "photos/plain/", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)] [OperationContract] ResultInfo UploadPlainPhoto(byte[] byteInfo); } 
  5. To check it, you can use fiddler
    First method:
    Uri: http:// localhost/imageservice/photos
    Header: Content-Type: application/json
    Request type: POST
    Request body:

    { "FileName": "sdfa", "Mode" : "StaffImage", "ID" : "2", "FileByte" : [1,2,3,4,5] }

EDIT 3:

As you have now different kind of exception related to too big message side, here are possible solutions:

  1. Try to add this to config:

     <system.web> <httpRuntime maxMessageLength="409600" executionTimeoutInSeconds="300"/> </system.web> 

    It will increase maximum message size to 400 Mb ( MSDN )

  2. Use streaming, which is prefereble, I would say: MSDN

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM