我创建了一个WCF服务来上传文件,WCF服务托管在Windows IIS上。我也有一个客户端通过HTTPS使用这个WCF服务,目前客户端和服务在同一台机器上。代码如下所示:
IService1.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;
namespace WcfService1
{
// NOTE: You can use the "Rename" command on the "Refactor" menu to change the interface name "IService1" in both code and config file together.
[ServiceContract]
public interface IService1
{
[OperationContract]
void UploadFile(RemoteFileInfo request);
// TODO: Add your service operations here
}
[MessageContract]
public class RemoteFileInfo : IDisposable
{
[MessageHeader(MustUnderstand = true)]
public string FilePath;
/*
[MessageHeader(MustUnderstand = true)]
public string DestinationDirectory;
*/
[MessageBodyMember(Order = 1)]
public System.IO.Stream FileByteStream;
public void Dispose()
{
if (FileByteStream != null)
{
FileByteStream.Close();
FileByteStream = null;
}
}
}
}
Service1.cvs.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using System.IO;
using System.ServiceModel.Web;
using System.Diagnostics;
namespace WcfService1
{
// NOTE: You can use the "Rename" command on the "Refactor" menu to change the class name "Service1" in code, svc and config file together.
// NOTE: In order to launch WCF Test Client for testing this service, please select Service1.svc or Service1.svc.cs at the Solution Explorer and start debugging.
public class Service1 : IService1
{
public void UploadFile(RemoteFileInfo request)
{
FileStream targetStream = null;
Stream sourceStream = request.FileByteStream;
//string destinationDirectory = request.DestinationDirectory;
Console.WriteLine(request.FilePath);
string fileName = Path.GetFileName(request.FilePath);
string filePath = Path.Combine("C:\\upload", fileName);
using (targetStream = new FileStream(filePath, FileMode.Create,
FileAccess.Write, FileShare.None))
{
const int bufferLen = 65000;
byte[] buffer = new byte[bufferLen];
int count = 0;
while ((count = sourceStream.Read(buffer, 0, bufferLen)) > 0)
{
targetStream.Write(buffer, 0, count);
}
targetStream.Close();
sourceStream.Close();
}
}
}
}
的web.config:
<?xml version="1.0"?>
<configuration>
<appSettings>
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
</appSettings>
<system.web>
<compilation targetFramework="4.5" />
<httpRuntime targetFramework="4.5"/>
</system.web>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior>
<!-- To avoid disclosing metadata information, set the values below to false before deployment -->
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
<!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
<protocolMapping>
<add binding="basicHttpsBinding" scheme="https" />
</protocolMapping>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
<!--
To browse web app root directory during debugging, set the value below to true.
Set to false before deployment to avoid disclosing web app folder information.
-->
<directoryBrowse enabled="true"/>
</system.webServer>
</configuration>
客户代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ClientApp.ServiceReference1;
namespace ClientApp
{
class Program
{
static void Main(string[] args)
{
Service1Client client = new Service1Client();
string FilePath1 = "C:\\Users\\user1\\Desktop\\data.csv";
System.IO.FileStream stream1 =
new System.IO.FileStream("C:\\Users\\user1\\Desktop\\data.csv",
System.IO.FileMode.Open, System.IO.FileAccess.Read);
string dest = "C:\\upload";
client.UploadFile(FilePath1, stream1);
client.Close();
}
}
}
此客户端代码抛出异常&#34; client.UploadFile(FilePath1,stream1); &#34; :
An unhandled exception of type 'System.ServiceModel.EndpointNotFoundException' occurred in mscorlib.dll
Additional information: There was no endpoint listening at http://localhost:53673/Service1.svc that could accept the message. This is often caused by an incorrect address or SOAP action. See InnerException, if present, for more details.
但是,如果我启动浏览器访问该站点,我可以成功访问Service1.svc(这意味着我配置了IIS并正确地将服务发布到IIS),如下面的屏幕截图所示:
我想知道问题出在哪里?提前谢谢!
编辑:
orignal客户端的App.config如下:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_IService1" />
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost:53673/Service1.svc" binding="basicHttpBinding"
bindingConfiguration="BasicHttpBinding_IService1" contract="ServiceReference1.IService1"
name="BasicHttpBinding_IService1" />
</client>
</system.serviceModel>
</configuration>
根据建议,我将其更改为:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
<system.serviceModel>
<bindings>
<basicHttpsBinding>
<binding name="BasicHttpsBinding_IService1" />
</basicHttpsBinding>
</bindings>
<client>
<endpoint address="https://localhost:53673/Service1.svc" binding="basicHttpsBinding"
bindingConfiguration="BasicHttpsBinding_IService1" contract="ServiceReference1.IService1"
name="BasicHttpsBinding_IService1" />
</client>
</system.serviceModel>
</configuration>
现在,我又遇到了另一个错误:
An unhandled exception of type 'System.ServiceModel.CommunicationException' occurred in mscorlib.dll
Additional information: An error occurred while making the HTTP request to https://localhost:53673/Service1.svc. This could be due to the fact that the server certificate is not configured properly with HTTP.SYS in the HTTPS case. This could also be caused by a mismatch of the security binding between the client and the server.
如果我可以从浏览器启动网站,我认为证书不存在问题。另外,我使用自签名证书,客户端和服务器在同一台机器上。我在想,如果我不能直接更改客户端的app.config,那么服务的配置有问题吗?我注意到每次在客户端服务引用中更新服务时,http绑定都会出现在app.config中。我想知道处理它的正确方法是什么?
答案 0 :(得分:1)
将客户端app.config文件更改为指向正确的地址。它目前指向:
<endpoint address="https://localhost:53673/Service1.svc" binding="basicHttpsBinding"
将地址部分更改为屏幕截图中屏蔽的部分。