【发布时间】:2015-10-14 04:05:47
【问题描述】:
我创建了一个 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();
}
}
}
此客户端代码在“client.UploadFile(FilePath1, stream1);”行抛出异常:
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),如下面的屏幕截图:
我想知道问题出在哪里?提前致谢!
编辑:
原始客户端的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中。我想知道处理它的正确方法是什么?
【问题讨论】:
-
虽然您在屏幕截图中隐藏了 URL,但很明显它不是您的客户指向的
http://localhost:53673/Service1.svc。 -
浏览器屏幕截图使用https,而您包含的错误消息显示http('没有端点在http://localhost:53673/Service1.svc')。将应用使用的 url 更改为使用 https
-
我想知道如何更改应用程序使用的网址?我的意思是我应该修改哪个文件?
标签: c# asp.net web-services wcf iis