【问题标题】:Error when accessing WCF Service with Byte parameter in Silverlight Application在 Silverlight 应用程序中使用 Byte 参数访问 WCF 服务时出错
【发布时间】:2014-06-01 23:10:45
【问题描述】:

我正在开发一个测试应用程序,我可以使用 Silver-light 应用程序将图像上传到 Web 服务器。

以下是我的 WCF SERVICE 的代码:

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

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

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>

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

错误详情

当我访问 DoSum() 方法时,它会返回正确的结果。但是当我尝试使用 Stream/Byte 参数调用任何方法时,我会收到以下错误:

[System.ServiceModel.CommunicationException] = {System.ServiceModel.CommunicationException:远程服务器返回错误:NotFound。 ---> System.Net.WebException:远程服务器返回错误:NotFound。 ---> System.Net.WebException:远程服务器返回错误:NotFound。 在系统...

编辑:------------------

当我将 Byte[] 更改为 string 时,它可以完美运行,我遇到了 byte[] 数据类型的问题,因为我需要 Stream/byte[] 将图像上传到服务器。有什么想法吗?

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

编辑:2---------------------

请检查以下屏幕截图,我无法将 maxReceivedMessageSize 设置为 WCF 服务,如果 Stream 内容很小,它会到达服务器,但不会很大。

谢谢

【问题讨论】:

  • 您是否设置了端点地址?我在配置中没有看到它。
  • 对不起,迟到的评论,你能解释一下我在这里缺少什么吗?我应该在 .config 文件中指定每个端点的地址吗?
  • 是的,你有。请看我的回答,因为在评论中配置 sn-p 看起来很丑。
  • 请在下面找到更新
  • 请在我的 EDIT 3 中找到更新后的新错误答案。

标签: c# asp.net .net wcf silverlight


【解决方案1】:

错误消息对我来说并没有什么意义。尝试打开WCF tracing。配置非常简单,但它是解决 WCF 问题的好工具。这通常会为您提供更具体、更友好的错误消息。

希望对你有帮助!

【讨论】:

    【解决方案2】:

    指定地址:

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

    您的客户使用的地址是:

    http://{MachineName}/imageservice
    

    如果您在 IIS 上托管您的应用程序,您需要有 svc 文件。并尝试了解您的服务是否启动。启用跟踪或设置错误处理:Error handling for WCF service

    编辑 1:

    我刚刚注意到您不使用命名空间 - 这是非常糟糕的做法。

    编辑 2:

    1. 尽量避免对 MessageContract 和 DataContract 使用 Order 属性,这不是好的做法。
    2. 您不应该使用消息契约,因为没有理由将它用于您的案例。您的数据合同应该是:

      [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. 您无需使用“[ServiceKnownType("GetKnownTypes", typeof(Helper))]”。

    4. 当您使用 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. 要检查它,你可以使用 fiddler
      第一种方法:
      URI:http://localhost/imageservice/photos
      标头:内容类型:应用程序/json
      请求类型:POST
      请求正文:

      { "文件名": "sdfa", “模式”:“员工形象”, “身份证”:“2”, “文件字节”:[1,2,3,4,5] }

    编辑 3:

    由于您现在有不同类型的与消息过大相关的异常,以下是可能的解决方案:

    1. 尝试将其添加到配置中:

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

      它将最大消息大小增加到 400 Mb (MSDN)

    2. 使用流式传输,我会说:MSDN

    【讨论】:

    • 其实这只是一个demo应用,所以急着做demo我没有使用namespace。但感谢您的建议。
    • 当我将 Byte[] 更改为 string 时,它工作得很好,我遇到了 byte[] 数据类型的问题,因为我需要 Stream/byte[] 将图像上传到服务器。有任何想法吗?请参阅我的问题中的编辑。
    猜你喜欢
    • 1970-01-01
    • 2012-04-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多