WCF自我寄宿(在VS2015)调式时,IE访问一切正常;部署到IIS10后, IE访问 svchelp正常,svcWebGet报错
如果你直接在IIS 7中配置WCF,访问svc文件时会出现404错误。
解决方法,以管理员身份进入命令行模式,运行:
"%windir%\MicrosoftNET\Framework\v30\Windows Communication Foundation\ServiceModelRegexe" -r -y
-r - 重新安装此版本的 Windows Communication Foundation,
并更新 IIS 元数据库根处的脚本映射和根以下的所有
脚本映射。无论原始版本是什么,都将现有的脚本映射
升级到此版本。
-y - 在卸载或重新安装组件之前不要求确认。
-------------------------------
一般是在安装 Windows Communication Foundation (WCF) 之后安装了 IIS造成,运行以上命令将在 IIS 中注册所需的脚本映射。
这时将确保在MIME中将 svc 文件类型映射到 aspnet_isapidll。
2
改个名字为“managerwsdl”
3
下一步,定义命名空间和协议等信息,默认即行
4
finish后,会在主工作区出现如下图
5
这是managerwsdl的图形化形式,点击“Source”会可查看到源代码
6
这是默认生成的wsdl,我们要根据我们的项目需要,修改上面的图,首先对方法名进行修改
7
修改之后,右边的input和output也跟着修改了,这两个就是定义plus的输入和输出。 点击input参数“plus”右边的提示箭头
8
就在这里定义输入参数和和参数类型等信息,因为我们plus(float x, float y)方法中有两个参数x和y,故我们将上图改成两个参数的序列
9
变成下图,对比一下方法plus(float x, float y)
我们返回managerwsdl视图,选择output参数右边的箭头
我们在这里设置float plus(float x, float y)方法的返回值及其类型,因其返回值只有一个,我们只须把上面的out的类型改成我们方法中用的float,改后,如下图
有没有注意到上图左上角有个 图标,点击它,进入下图
好了,我们再回到managerwsdl,在源代码视图里右键选“Validate”,对xml文档进行检验,如果有错误的,就根据需要修改。
好了,图形化编写的wsdl文档完成了,顺便说一下,方法是可以定义多个的
为简单起见,我们就先以刚才做定义的那个方法为例,看看,如何根据wsdl文件,自动生成Web Service的服务器端。
我们New一个Web Service
在Web Service type中选择“Top down Java Bean Web Service”
在Service definition中找到刚才写的那个managerwsdl文件
Web Service对话框,将服务类型的滑块调到“Develop service”处
接下来,就next –> next –-> finish就行。它会自动生成Web Service服务端的接口和类,在类中,可找到我们定义的方法
20
我们只要修改方法plus的方法体,以实现我们要实现的功能即行。
回答不容易,希望能帮到您,满意请帮忙采纳一下,谢谢 !
主要的原因在于重新部署和访问权限的问题。
如果你修改了DLL内容,那么你必须要将修改DLL发送到客户端,如果你的DLL改了文件名,你的客户端必须要更新所有调用它文件;而是用WCF就没有这样的问题,你只需要更新WCF就可以,
而将DLL直接部署到客户端,且这个DLL是和有访问限制的内容打交道的。即便你在DLL中设置的访问权限什么的。但你要知道,在客户机上运行的程序都是在客户机内存的,破解本地的数据要比黑掉服务器来的简单的多;并且,如果将DLL部署在客户端,那么就相当于所有的客户机都是直接于数据服务器相连的,为黑掉服务器打开了方便之门。
说白了,就和网络游戏的客户端和服务器一样的道理。为什么网游的客户端不直接连数据库处理,非得花大价钱用服务器,所谓的分布式计算不是很好么。道理就是这样的,一个是安全,一个方便更新和控制
功能介绍 主要是使用WCF框架实现从客户端上传到服务端并在服务端显示的基本功能 一 首先创建两Windows窗体应用程序 WinFormClient (客户端 发送端)和 WinFormReceiver (接收端) 如图设计FormClient(发送端窗体)的界面 上边是一个panel容器中添加了一个TextBox和 两个Button 下边是一个PictureBox控件(用于浏览上传之前的)
然后添加浏览按钮下的后台代码 实现客户端浏览的功能 View Code string fileName = ;//定义一个全局变量 //浏览选择上传内容 private void btnBrowser_Click(object sender EventArgs e) { //string fileName = ;//定义一个字段用于获取上传的文件名 OpenFileDialog openFileDialog = new OpenFileDialog() //创建一个OpenFileDialog对象专门用于打开文件 if (openFileDialog ShowDialog() == DialogResult OK)//打开的文件对话框如果选择了OK按钮(确定) 则为真 执行大括号中的内容 { fileName = openFileDialog FileName; txtPicName Text = fileName;//在textBox中显示文件名 pictureBox Load(fileName) //使该在客户端pictuBox中显示 } else return;//未选中文件则返回 } 将WinFomClient设为启动项目 运行 当你选择后 该会显示在发送端的窗体中 供发送者浏览 如需更改上传可重新选取 该将会被覆盖掉 (上传功能将在下文实现) FormReceiver接收端的窗体只需添加一个PictureBox控件 用于显示客户端上传的
二 在解决方案中添加两个类库 ITransferPic(接口) TransferPic(继承接口) 一个控制台应用程序 TransferPicHost(宿主程序) 该实例采用的是 自身托管宿主 并非 IIS宿主 ITransferPic ( ) 添加引用 using System ServiceModel; using System IO; ( ) 创建一个 ITransferPicService 接口 View Code [ServiceContract] public interface ITransferPicService { [OperationContract]//操作契约 Stream GetPic() [OperationContract] void SendPic(Stream transferPic) } TransferPic ( ) 添加引用 using ITransferPic; using System IO; ( ) 创建一个 TransferPicService 类 继承接口 ITransferPicService 并实现该接口 View Code public class TransferPicService : ITransferPicService { public static Stream PicSource = new MemoryStream() /// <summary> /// 从服务端下载到本地 (上传和下载都是拷贝的过程) /// </summary> /// <returns></returns> public Stream GetPic() { MemoryStream ms = new MemoryStream() PicSource Position = ;//指明从第 位开始拷贝 PicSource CopyTo(ms) //服务端将客户端的Stream复制一份 ms Position = ;//注意如果缺少该条代码接收端将无法显示上传 return ms;//然后在返回客户端 } /// <summary> /// 从客户端上传到服务端(将客户端的Stream拷贝给服务端的Stream) /// </summary> /// <param name= transferPic ></param> public void SendPic(Stream transferPic) { PicSource Position = ; transferPic CopyTo(PicSource) } } TransferPicHose 自身托管宿主 利用WCF提供的ServiceHost<T>提供的Open()和Close()方法 可以便于开发者在控制台应用程序 Windows应用程序乃至于ASP NET应用程序中托管服务 不管自宿主的环境是何种应用程序 实质上托管服务的方式都是一致的 如该实例中用到的代码部分 添加引用 using System ServiceModel; using ITransferPic; using System ServiceModel Description; View Code class Program { static void Main(string[] args) { NetTcpBinding bind = new NetTcpBinding() bind MaxBufferSize = ; bind TransferMode = TransferMode Streamed; bind MaxReceivedMessageSize = ; bind Security Mode = SecurityMode None; //超出using 范围程序会自动释放 using (ServiceHost host = new ServiceHost(typeof(TransferPic TransferPicService))) { host AddServiceEndpoint(typeof(ITransferPicService) bind net tcp://localhost: /transferPic ) //该地址为宿主地址 和客户端接收端地址保持一致if (host Description Behaviors Find<ServiceMetadataBehavior>() == null) { ServiceMetadataBehavior behavior = new ServiceMetadataBehavior() behavior HttpGetEnabled = true; behavior HttpGetUrl = new Uri(//localhost: /transferPic/metadata/ ) host Description Behaviors Add(behavior) } host Opened += delegate { Console WriteLine( 程序已成功启动! ) }; host Open() Console ReadLine() } } } 三 实现上传 WinFormClient 后台上传按钮部分 添加引用 using System IO; using System ServiceModel; using ITransferPic; View Code //执行上传功能 private void btnUpload_Click(object sender EventArgs e) { //pictureBox Load(fileName) //读取流 上传文件流到服务器 FileStream fs = new FileStream(fileName FileMode Open FileAccess Read) //创建一个文件 并把文件放在文件流里边 Stream = new MemoryStream() //创建一个滤层流 将文件从第 位拷贝到 中 fs Position = ;//获取或设置此流的当前位置 fs CopyTo( ) //拷贝完成之后进行上传 EndpointAddress epAddr = new EndpointAddress( net tcp://localhost: /transferPic ) //此处也可以用IIS做服务 NetTcpBinding bind = new NetTcpBinding() //绑定方式 bind MaxBufferPoolSize = ;//最大缓冲 bind TransferMode = TransferMode Streamed;//传输模式为流式处理 bind MaxReceivedMessageSize = ;//定义了服务端接收Message的最大长度 防止文件过大 bind Security Mode = SecurityMode None;//安全模式设置为不进行验证 //创建一个工厂 ITransferPicService proxy = ChannelFactory<ITransferPicService> CreateChannel(bind epAddr) Position = ; proxy SendPic( ) //WCF客户端调用该方法 把客户端 上传到服务端去 } WinFormReceiver 后台 添加引用 using ITransferPic; using System IO; using System ServiceModel; View Code private void FormReceiver_Load(object sender EventArgs e) { Thread myThread = new Thread(ShowPic) //创建一个线程 myThread IsBackground = true;//设置后台线程(防止主程序关闭后 仍在运行) myThread Start() //启动线程 } public void ShowPic() { #region 同客户端一样 创建WCF客户端 EndpointAddress epAddr = new EndpointAddress( net tcp://localhost: /transferPic ) NetTcpBinding bind = new NetTcpBinding() bind MaxBufferPoolSize = ; bind TransferMode = TransferMode Streamed; bind MaxReceivedMessageSize = ; bind Security Mode = SecurityMode None;
//创建一个通道 ITransferPicService proxy = ChannelFactory<ITransferPicService> CreateChannel(bind epAddr) #endregion while (true) { Stream streamFromServer = proxy GetPic() //返回一个文件流 MemoryStream ms = new MemoryStream() //滤层流拷贝一份 ms Position = ; streamFromServer CopyTo(ms) //将该文件流拷贝给到ms; if (ms Length == ) { System Threading Thread Sleep( ) // 百毫秒执行一次 continue; } Bitmap tn = new Bitmap(ms) //创建一个位图 把ms变成 pictureBox Image = tn; System Threading Thread Sleep( ) // 百毫秒执行一次 Sleep表示当前线程挂起指定的时间 } } 四 运行程序 打开TransferPicHost 文件中bin目录 启动 TransferPicHost exe 此时会弹出一个控制台应用程序的窗体 并提示 功能已成功启动! 分别启动发送端和接收端项目程序 (将 WinFormClient 或者 WinFormReceiver 设为启动项目 并启动另一个项目文件夹bin目录下的 WinFormReceiver exe 或者 WinFormClient exe ) 点击发送端 浏览按钮 进行选择 之后点击 上传按钮 这时 你会发现客户端上传的显示在了接收端的窗体上 程序运行成功 lishixinzhi/Article/program/net/201311/12342
Silverlight项目中添加服务引用后会在Silverlight项目中生成一个ServiceReferencesClientConfig文件,这个文件中包含了引用服务的绑定(bindings)和终结点(Endpoint)的配置信息。下面是引用一个WCF服务后自动生成的配置信息:
<configuration>
<systemserviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_IService1" maxBufferSize="2147483647"
maxReceivedMessageSize="2147483647">
<security mode="None" />
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost:4177/Services/Service1svc"
binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IService1"
contract="ServiceReference1IService1" name="BasicHttpBinding_IService1" />
</client>
</systemserviceModel>
</configuration>
在程序开发阶段,使用上面的配置信息不会有什么错误。在部署程序时,服务的地址通常和开发时使用的服务地址是不一样的,这时就需要修改上面的配置信息中的终结点的地址。但是Silverlight项目编译后会将ServiceReferencesClientConfig嵌入到生成的xap文件中,这给修改带来了一定难度。
该解决方案目前使用会话(在ITestServicecs):
[的ServiceContract(SessionMode = SessionModeRequired)]
和使用的wsHttpBinding(见下面的appconfig和网络。 。配置)
当我部署此到服务器时,我能够成功使用HTTPS像这样通过网络浏览器来访问它:的 https://myservercom/test/testservicesvc
不过当我在客户端的appconfig更改端点的:
的http://本地主机:20616 / TestServicesvc / TestServicesvc
到
https://myservercom/test/testservicesvc
并再次运行控制台应用程序,我收到错误:“提供的URI方案的”https“是无效的;预计“HTTP”。参数名:通过“
我的问题是,什么是我需要做这个工作的最小的变化,在不改变SessionModeRequired
下面是客户端的控制台应用程序代码,请务必改变在appconfig值“mycomputer\Matt”,以正确的价值为您的机器。
的Programcs
使用系统;
命名TestClient的
{
类节目
{
静态无效的主要(字串[] args)
{
控制台Clear();
ConsoleWriteLine(“尝试登录”);
试
{
TestServiceReferenceTestServiceClient客户端=新TestServiceReferenceTestServiceClient();
布尔loginSuccess = clientLogIn(“管理员”,“密码”);
如果(loginSuccess)
{
ConsoleWriteLine(“成功登录。 “);
串secretMessage = clientGetSecretData();
ConsoleWriteLine(“检索秘密信息:”+ secretMessage);
}
,否则
{
ConsoleWriteLine(“登录失败!”);
}
}
赶上(例外EXC)
{
ConsoleWriteLine(“异常:”+ excMessage);
}
ConsoleWriteLine(“按ENTER键退出。”);
到ConsoleReadLine();
}
}
}
的Appconfig :
< XML版本=“10”编码=“UTF-8”>?
<结构>
<&启动GT;
< supportedRuntime版本=“V40”SKU =“net框架,版本= V451”/>
< /启动>
< systemserviceModel>
<&绑定GT;
<&的wsHttpBinding GT;
<绑定名称=“WSHttpBinding_ITestService”/>
< /&的wsHttpBinding GT;
< /绑定>
<客户端>
<端点地址=“https://myservercom/test/testservicesvc”绑定=“的wsHttpBinding”bindingConfiguration =“WSHttpBinding_ITestService”合同=“TestServiceReferenceITestService”NAME =“WSHttpBinding_ITestService”>
<同一性GT;
<的UserPrincipalName值=“mycomputer\Matt”/>
< /身份>
< /端点> !
< - <端点地址=“HTTP://本地主机:20616 / TestServicesvc / TestServicesvc”绑定=“的wsHttpBinding”bindingConfiguration =“WSHttpBinding_ITestService”合同=“TestServiceReferenceITestService”NAME = “WSHttpBinding_ITestService”>
<同一性GT;
<的UserPrincipalName值=“mycomputer\Matt”/>
< /身份>
< /端点> - >
< /客户>
< /systemserviceModel>
< /结构>
WCF服务代码结果
ITestServicecs:
使用SystemServiceModel;
命名空间WcfSessionsOverHttpsTest
{
[的ServiceContract(SessionMode = SessionModeRequired)]
公共接口ITestService
{
[ OperationContract的(IsInitiating =真)]
布尔登录(用户名字符串,字符串密码);
[OperationContract的(IsInitiating =假,IsTerminating = TRUE)]
布尔注销();
[OperationContract的(IsInitiating = FALSE)]
串GetSecretData();
}
}
TestServicesvc:
命名空间WcfSessionsOverHttpsTest
{
公共类TestService的:ITestService
{
公布尔IsAuthenticated {搞定;组; }
布尔ITestServiceLogIn(用户名字符串,字符串密码)
{
如果(用户名==“管理员”&放大器;&放大器;密码==“密码”)
$ { b $ b IsAuthenticated = TRUE;
返回真;
}
,否则
{
IsAuthenticated = FALSE;
返回FALSE;
}
}
布尔ITestServiceLogOut()
{
IsAuthenticated = FALSE;
返回真;
}
串ITestServiceGetSecretData()
{
如果(!IsAuthenticated)
{
抛出新SystemSecurityAuthentication。的AuthenticationException(“用户还没有登录。”);
}
,否则
{
串secretMessage =“红袜会赢得世界系列在2016年”;
返回secretMessage;
}
}
}
}
的Webconfig:
< XML版本=“10”>?
<结构>
<&的appSettings GT;
<添加键=“ASPNET:UseTaskFriendlySynchronizationContext”VALUE =“真”/>
< /的appSettings>
<&的SystemWeb GT;
<编译调试=“真”targetFramework =“451”/>
<的httpRuntime targetFramework =“45”/>
< /systemweb>
< systemserviceModel>
<&绑定GT;
<&的wsHttpBinding GT;
<绑定名称=“wsHttpEndpointBinding”closeTimeout =“00:10:00”openTimeout =“00:10:00”receiveTimeout =“00:10:00”的SendTimeout =“00:10:00”maxReceivedMessageSize = “2147483647”>
< readerQuotas MAXDEPTH =“2147483647”maxStringContentLength =“2147483647”maxArrayLength =“2147483647”maxBytesPerRead =“2147483647”maxNameTableCharCount =“2147483647”/>
< /&结合GT;
< /&的wsHttpBinding GT;
< /绑定>
<服务和GT;
<服务名称=“WcfSessionsOverHttpsTestTestService”>
<端点地址=“/ TestServicesvc”绑定=“的wsHttpBinding”bindingConfiguration =“wsHttpEndpointBinding”合同=“WcfSessionsOverHttpsTestITestService”/>
< /服务>
< /服务>
<&行为GT;
< serviceBehaviors>
<&行为GT;
< serviceMetadata httpGetEnabled =“真”httpsGetEnabled =“真”/>
< serviceDebug includeExceptionDetailInFaults =“FALSE”/>
< /行为>
< / serviceBehaviors>
< /行为>
< protocolMapping>
<添加绑定=“的wsHttpBinding”计划=“HTTP”/>
< / protocolMapping>
< serviceHostingEnvironment aspNetCompatibilityEnabled =“真”multipleSiteBindingsEnabled =“真”/>
< /systemserviceModel>
< systemwebServer>
<模块runAllManagedModulesForAllRequests =“真”/>
<启用directoryBrowse =“真”/>
< /systemwebServer>
< /结构>
在此先感谢您的帮助!
太
解决方案
解决这个问题是我需要补充的是,从派生的类“UserNamePasswordValidator”并注册它的WebConfig
公共类CustomUserNameValidator:UserNamePasswordValidator
{
公覆盖void验证(用户名字符串,字符串密码)
{
的回报;
}
}
Webconfig文件:
<&行为GT;
< serviceBehaviors>
<&行为GT;
<! - 为了避免泄露的元数据信息,在部署之前设置以下为false值 - >
< serviceMetadata httpsGetEnabled =“真”/>
<! - 要接收的异常细节的故障进行调试,下面设置为true值。设置为false部署之前,以避免泄露异常信息 - >
< serviceDebug includeExceptionDetailInFaults =“真”/>
< serviceCredentials>
< userNameAuthentication userNamePasswordValidationMode =“自定义”customUserNamePasswordValidatorType =“MyProgramCustomUserNameValidator,MyProgram”/>
< / serviceCredentials>
< /行为>
< / serviceBehaviors>
< /行为>
网站模板库 » WCF自我寄宿(在VS2015)调式时,IE访问一切正常;部署到IIS10后, IE访问 svchelp正常,svcWebGet报错
0条评论