简体   繁体   English

在Silverlight应用程序中使用Byte参数访问WCF服务时出错

[英]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. 我正在开发一个测试应用程序,可以在其中使用Silver-light应用程序将图像上传到Web服务器。

Following is the code of my WCF SERVICE: 以下是我的WCF服务的代码:

Code of IImageService.cs 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 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 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 Silverlight应用程序中的代码

  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. 当我访问DoSum()方法时,它将返回正确的结果。 But when I try to call any method with Stream/Byte parameter then I get following error: 但是,当我尝试使用Stream / Byte参数调用任何方法时,出现以下错误:

[System.ServiceModel.CommunicationException] = {System.ServiceModel.CommunicationException: The remote server returned an error: NotFound. [System.ServiceModel.CommunicationException] = {System.ServiceModel.CommunicationException:远程服务器返回错误:未找到。 ---> System.Net.WebException: The remote server returned an error: NotFound. ---> System.Net.WebException:远程服务器返回错误:NotFound。 ---> System.Net.WebException: The remote server returned an error: NotFound. ---> System.Net.WebException:远程服务器返回错误:NotFound。 at Syst... 在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. 当我将Byte []更改为字符串然后可以正常工作时,byte []数据类型存在问题,因为我需要Stream / byte []将图像上传到服务器。 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--------------------- 编辑: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. 请检查以下屏幕快照,我无法将maxReceivedMessageSize设置为WCF Service,如果Stream内容很小,则可以到达服务器,但不能很大。

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

Thanks 谢谢

The error message doesn't say much to me. 错误消息对我说的不多。 Try turning on WCF tracing . 尝试打开WCF跟踪 Very simple to configure but is a great tool for troubleshooting WCF issues. 配置非常简单,但是是解决WCF问题的好工具。 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. 如果您将应用程序托管在IIS上,则需要具有svc文件。 And try to understand if you service start. 并尝试了解您是否开始维修。 Enable tracing for that or set up error handling: Error handling for WCF service 为此启用跟踪或设置错误处理: WCF服务的错误处理

EDIT 1: 编辑1:

I've just notice that you don't use namespace - it's really bad practice. 我刚刚注意到您不使用名称空间-这确实是一种不好的做法。

EDIT 2: 编辑2:

  1. Try to avoid using Order property for MessageContract and DataContract, it's not good practice. 尽量避免对MessageContract和DataContract使用Order属性,这不是一个好习惯。
  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. 不需要为您使用“ [ServiceKnownType(“ GetKnownTypes”,typeof(Helper))]”。

  4. As you use WebHttpBinding you have to apply WebGet, WebInvoke attributes: 使用WebHttpBinding时,必须应用WebGet,WebInvoke属性:

     [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 Uri:http:// localhost / imageservice / photos
    Header: Content-Type: application/json 标头:Content-Type:application / json
    Request type: POST 请求类型:POST
    Request body: 要求正文:

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

EDIT 3: 编辑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 ) 它将最大邮件大小增加到400 Mb( MSDN

  2. Use streaming, which is prefereble, I would say: MSDN 使用流媒体,这是可取的,我会说: MSDN

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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