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

时间:2014-04-17 15:28:30

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

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

以下是我的WCF服务的代码:

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。 ---&GT; System.Net.WebException:远程服务器返回错误:NotFound。 ---&GT; System.Net.WebException:远程服务器返回错误:NotFound。    在Syst ......

修改:------------------

当我将Byte []更改为字符串然后它完美地工作时,我遇到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内容很小,它会到达服务器,但不会很大。

This is the Request body This is Response body

由于

2 个答案:

答案 0 :(得分:0)

错误消息对我说不多。尝试启用WCF tracing。配置非常简单,但却是解决WCF问题的绝佳工具。这通常会为您提供更具体和友好的错误消息。

希望它有所帮助!

答案 1 :(得分:0)

指定地址:

<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
    标题:内容类型:application / json
    请求类型:POST
    请求正文:

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

  6. 编辑3:

    由于您现在有与消息方面相关的不同类型的异常,这里有可能的解决方案:

    1. 尝试将此添加到配置:

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

      它会将最大邮件大小增加到400 Mb(MSDN

    2. 使用流媒体,这是优先的,我会说:MSDN