I have a token issuer WCF service which is using Microsoft.IdentityModel (WIF 3.5) that I need to upgrade to System.IdentityModel (.NET 4.5). The problem is that I can't change the original name of the service , Microsoft.IdentityModel.Protocols.WSTrust.WSTrustServiceContract
, to it's newer counterpart, System.ServiceModel.Security.WSTrustServiceContract
. For some reason it's not recognized by IntelliSense:
我有一个令牌发行人WCF服务,使用的是微软。我需要升级到系统的IdentityModel (WIF 3.5)。IdentityModel(。NET 4.5)。问题是我不能更改服务的原始名称microsoft.identitymodel . protocol . wstrust。WSTrustServiceContract,它的更新版本,System.ServiceModel.Security.WSTrustServiceContract。出于某种原因,智能感知无法识别它:
The blue squiggly line error is:
蓝色弯角线误差为:
The 'name' attribute is invalid - The value 'System.ServiceModel.Security.WSTrustServiceContract' is invalid according to its datatype 'serviceNameType'
I do have assembly references to System.ServiceModel
and System.IdentityModel
in <assemblies>
node.
我确实有对系统的汇编引用。ServiceModel和系统。IdentityModel在 <组件> 节点。
Even when I ignore the IntelliSense error and run the service and access it using browser I'm getting this metadata error:
即使我忽略了智能感知错误并运行服务并使用浏览器访问它,我也会得到这个元数据错误:
Metadata publishing for this service is currently disabled.
Metadata publishing is enabled so I think it's because of the name problem of the service.
元数据发布是启用的,所以我认为这是因为服务的名称问题。
Also I'm getting this error from the VS.NET WCF test client:
我也从VS.NET WCF测试客户端得到这个错误:
Error: Cannot obtain Metadata from http://localhost:49178/Services/Issuer.svc
If this is a Windows (R) Communication Foundation service to which you have access, please check that you have enabled metadata publishing at the specified address. For help enabling metadata publishing, please refer to the MSDN documentation at http://go.microsoft.com/fwlink/?LinkId=65455.
WS-Metadata Exchange Error
URI: http://localhost:49178/Services/Issuer.svc
Metadata contains a reference that cannot be resolved: 'http://localhost:49178/Services/Issuer.svc'.
There was no endpoint listening at http://localhost:49178/Services/Issuer.svc that could accept the message. This is often caused by an incorrect address or SOAP action. See InnerException, if present, for more details.
The remote server returned an error: (404) Not Found.
HTTP GET Error
URI: http://localhost:49178/Services/Issuer.svc
The HTML document does not contain Web service discovery information.
I think the "Metadata contains a reference that cannot be resolved
" line also refers to the service name resolve error.
我认为“元数据包含一个无法解析的引用”行也指服务名解析错误。
Any ideas on what to do here? I'd appreciate any help..
有什么办法吗?我感谢任何帮助。
Issuer.svc:
Issuer.svc:
<%@ ServiceHost Language="C#" Debug="true" Factory="Identity.Services.Wcf.Core.CustomSecurityTokenServiceContractFactory" Service="CustomSecurityTokenServiceConfiguration" %>
Factory:
工厂:
public class CustomSecurityTokenServiceContractFactory : WSTrustServiceHostFactory
..
Service:
服务:
public class CustomSecurityTokenServiceConfiguration : SecurityTokenServiceConfiguration
..
2 个解决方案
#1
3
Sometimes the best way to solve this kind of problems is to create a new WCF project from scratch, configure again your endpoints etc.. and copying over your existing services from your old project, this is especially true when moving from an older version of WCF.
有时解决此类问题的最佳方法是从头创建一个新的WCF项目,重新配置端点等。从旧的项目中复制现有的服务,这一点尤其适用于从旧版本的WCF中移动。
Here is a checklist that I follow every time I have problems with WCF services:
以下是我每次在WCF服务中遇到问题时都会遵循的清单:
The Server
服务器
Make sure your service contracts are defined using interfaces with the appropriate attributes, for example:
确保您的服务契约是使用具有适当属性的接口定义的,例如:
IMyService.cs
IMyService.cs
[ServiceContract]
public interface IMyService
{
[OperationContract]
int ThisAnOperation(int a, int b);
}
Check that you have implemented your contracts using the right interface:
检查您是否使用正确的接口实现了您的合同:
MyService.cs
MyService.cs
public class MyService: IMyService
{
public int ThisAnOperation(int a, int b)
{
return a * b;
}
}
You need to have a service host to access your service, they are the files with the extension .svc:
您需要有一个服务主机来访问您的服务,它们是带有扩展名的文件。
- Create a file myService.svc.
- myService.svc创建一个文件。
-
Add the following line of code, referencing the class implementing your service:
添加以下代码行,引用实现服务的类:
<%@ ServiceHost Language="C#" Debug="true" Service="YourNamespace.MyService" CodeBehind="MyService.cs" %>
<%@ ServiceHost语言=" c# " Debug="true" Service="YourNamespace "。后台代码= MyService”“MyService。cs " % >
Finally, you need to set up a binding which will define which transports and protocols are available to access your server, start with a simple basic HTTP binding to check that your service is working as expected, then change it to something more production ready that includes authentication and/or encryption and compression as needed.
最后,您需要设置一个绑定定义可用的传输和协议来访问您的服务器,开始用一个简单的基本的HTTP绑定来检查你的服务是按预期工作,然后改变它生产更多的东西准备好,包括身份验证和/或根据需要加密和压缩。
To setup basic HTTP binding:
设置基本的HTTP绑定:
-
Remove the block
<system.serviceModel>...</system.serviceModel>
from your file web.config if it's already there.删除块< system.serviceModel >…< /系统。文件web上的serviceModel>。配置如果已经存在了。
-
Build your solution, it should compile successfully, otherwise fix any error and try again.
构建您的解决方案,它应该成功编译,否则修复任何错误并再次尝试。
-
Right-click your web.config file and then click on "Edit WCF Configuration", then click on "Create a New Service" and in Service type, browse and choose the DLL file generated when you compiled your service (should be in the bin folder) and select the service class you would like to publish:
右键单击您的web。配置文件,点击“编辑WCF配置”,点击“创建新服务”,在服务类型中,浏览选择编译服务时生成的DLL文件(应该在bin文件夹中),选择想要发布的服务类:
-
Specify the contract for the service (should be automatically filled up).
指定服务的合同(应该自动填写)。
-
In the next page select the transport protocol for your service, in this case, "HTTP", then select "Basic Web Services interoperability".
在下一页中为您的服务选择传输协议,在本例中是“HTTP”,然后选择“基本Web服务互操作性”。
-
In the next page you can specify the address for the endpoint, for testing purposes, you can leave this field empty (make sure you also remove "HTTP" from the text field).
在下一个页面中,您可以为端点指定地址,为了测试目的,您可以将该字段保留为空(确保您还可以从文本字段中删除“HTTP”)。
-
Click next, close the configuration window and save.
单击next,关闭配置窗口并保存。
Now you should be able to run the service and browse to MyService.svc to access your service.
现在您应该能够运行服务并浏览到MyService。访问您的服务的svc。
-
Activate metadata publishing so your service can be found, to do this, add the following behavior to your web.config:
激活元数据发布,以便找到您的服务,为此,将以下行为添加到您的web.config:
<system.serviceModel> <services> <service name="WcfService1.MyService"> <endpoint binding="basicHttpBinding" bindingConfiguration="" contract="WcfService1.IMyService" BehaviorConfiguration="MyServiceBehaviors" /> </service> </services> </system.serviceModel> <behaviors> <serviceBehaviors> <behavior name="MyServiceBehaviors" > <serviceMetadata httpGetEnabled="true" /> </behavior> </serviceBehaviors> </behaviors>
Now you should be able to run your project and get a metadata description page of your service within the browser, this info can be used by clients to find the service and generate a proxy of the service:
现在您应该可以在浏览器中运行您的项目并获得服务的元数据描述页面,客户可以使用此信息查找服务并生成服务的代理:
The Client
客户端
- Delete any existing service references from your project.
- 从项目中删除任何现有的服务引用。
- Right click on your project name then in "Add Service Reference", input your service address and click on "Go", if everything went all right you should see your service in the Service Window:
- 右键单击项目名称,然后在“添加服务引用”中,输入您的服务地址并点击“Go”,如果一切正常,您应该在服务窗口中看到您的服务:
-
Try to generate the proxy by finishing the wizard, rebuild your project and try it. If you still have the same problem, delete the generated reference and repeat points 1 and 2 and then:
尝试通过完成向导来生成代理,重新构建项目并尝试它。如果您仍然有同样的问题,删除生成的引用,重复点1和2,然后:
-
Click on "Advanced" and uncheck "Reuse types in referenced assemblies":
点击“高级”,取消“引用程序集中的重用类型”:
Then finish the wizard and compile.
然后完成向导并编译。
Hopefully, everything should work now!!!
希望现在一切都顺利!!
#2
1
I may have a similar setup as yours. In my case, I have both the STS and a service that is called by whoever wants a token. This is what you have, right?
我可能有一个类似你的设置。在我的例子中,我有STS和一个服务,任何需要令牌的人都可以调用它。这就是你所拥有的,对吧?
In the Web.config for the actual STS I have:
在Web。我的实际STS配置:
<bindings>
<ws2007HttpBinding>
<binding name="ws2007HttpBindingConfiguration">
<security mode="TransportWithMessageCredential">
<message establishSecurityContext="false" clientCredentialType="Certificate"/>
</security>
</binding>
</ws2007HttpBinding>
</bindings>
<services>
<service name="System.ServiceModel.Security.WSTrustServiceContract" behaviorConfiguration="STSBehavior">
<endpoint address="IWSTrust13" binding="ws2007HttpBinding" bindingConfiguration="ws2007HttpBindingConfiguration" contract="System.ServiceModel.Security.IWSTrust13SyncContract" name="STSWCF"/>
<endpoint address="mex" binding="mexHttpsBinding" contract="IMetadataExchange"/>
</service>
</services>
And in the Web.config for the service I have:
和网络。我拥有的服务配置:
<protocolMapping>
<!-- We want to use ws2007FederationHttpBinding over HTTPS -->
<add scheme="https" binding="ws2007FederationHttpBinding" bindingConfiguration="ws2007FederationHttpBindingConfiguration"/>
</protocolMapping>
<bindings>
<ws2007FederationHttpBinding>
<binding name="ws2007FederationHttpBindingConfiguration">
<!-- We expect a bearer token sent through an HTTPS channel -->
<security mode="TransportWithMessageCredential">
<message establishSecurityContext="false">
<issuerMetadata address="https://localhost/Identity.STS.WCF/Service.svc/mex"/>
</message>
</security>
</binding>
</ws2007FederationHttpBinding>
</bindings>
<services>
<service name="Identity.Auth.WCF.Service" behaviorConfiguration="STSBehavior">
<endpoint address="https://localhost/Identity.Auth.WCF/Service.svc" binding="ws2007FederationHttpBinding" bindingConfiguration="ws2007FederationHttpBindingConfiguration" contract="Identity.Auth.WCF.IService" name="Identity.Auth.WCF"/>
</service>
</services>
Also, it does work for me here, even though I do get the same IntelliSense error as you, and in the very same spot.
同样,它在这里对我也适用,尽管我确实得到了和你们一样的智能感知错误,在同样的位置。
#1
3
Sometimes the best way to solve this kind of problems is to create a new WCF project from scratch, configure again your endpoints etc.. and copying over your existing services from your old project, this is especially true when moving from an older version of WCF.
有时解决此类问题的最佳方法是从头创建一个新的WCF项目,重新配置端点等。从旧的项目中复制现有的服务,这一点尤其适用于从旧版本的WCF中移动。
Here is a checklist that I follow every time I have problems with WCF services:
以下是我每次在WCF服务中遇到问题时都会遵循的清单:
The Server
服务器
Make sure your service contracts are defined using interfaces with the appropriate attributes, for example:
确保您的服务契约是使用具有适当属性的接口定义的,例如:
IMyService.cs
IMyService.cs
[ServiceContract]
public interface IMyService
{
[OperationContract]
int ThisAnOperation(int a, int b);
}
Check that you have implemented your contracts using the right interface:
检查您是否使用正确的接口实现了您的合同:
MyService.cs
MyService.cs
public class MyService: IMyService
{
public int ThisAnOperation(int a, int b)
{
return a * b;
}
}
You need to have a service host to access your service, they are the files with the extension .svc:
您需要有一个服务主机来访问您的服务,它们是带有扩展名的文件。
- Create a file myService.svc.
- myService.svc创建一个文件。
-
Add the following line of code, referencing the class implementing your service:
添加以下代码行,引用实现服务的类:
<%@ ServiceHost Language="C#" Debug="true" Service="YourNamespace.MyService" CodeBehind="MyService.cs" %>
<%@ ServiceHost语言=" c# " Debug="true" Service="YourNamespace "。后台代码= MyService”“MyService。cs " % >
Finally, you need to set up a binding which will define which transports and protocols are available to access your server, start with a simple basic HTTP binding to check that your service is working as expected, then change it to something more production ready that includes authentication and/or encryption and compression as needed.
最后,您需要设置一个绑定定义可用的传输和协议来访问您的服务器,开始用一个简单的基本的HTTP绑定来检查你的服务是按预期工作,然后改变它生产更多的东西准备好,包括身份验证和/或根据需要加密和压缩。
To setup basic HTTP binding:
设置基本的HTTP绑定:
-
Remove the block
<system.serviceModel>...</system.serviceModel>
from your file web.config if it's already there.删除块< system.serviceModel >…< /系统。文件web上的serviceModel>。配置如果已经存在了。
-
Build your solution, it should compile successfully, otherwise fix any error and try again.
构建您的解决方案,它应该成功编译,否则修复任何错误并再次尝试。
-
Right-click your web.config file and then click on "Edit WCF Configuration", then click on "Create a New Service" and in Service type, browse and choose the DLL file generated when you compiled your service (should be in the bin folder) and select the service class you would like to publish:
右键单击您的web。配置文件,点击“编辑WCF配置”,点击“创建新服务”,在服务类型中,浏览选择编译服务时生成的DLL文件(应该在bin文件夹中),选择想要发布的服务类:
-
Specify the contract for the service (should be automatically filled up).
指定服务的合同(应该自动填写)。
-
In the next page select the transport protocol for your service, in this case, "HTTP", then select "Basic Web Services interoperability".
在下一页中为您的服务选择传输协议,在本例中是“HTTP”,然后选择“基本Web服务互操作性”。
-
In the next page you can specify the address for the endpoint, for testing purposes, you can leave this field empty (make sure you also remove "HTTP" from the text field).
在下一个页面中,您可以为端点指定地址,为了测试目的,您可以将该字段保留为空(确保您还可以从文本字段中删除“HTTP”)。
-
Click next, close the configuration window and save.
单击next,关闭配置窗口并保存。
Now you should be able to run the service and browse to MyService.svc to access your service.
现在您应该能够运行服务并浏览到MyService。访问您的服务的svc。
-
Activate metadata publishing so your service can be found, to do this, add the following behavior to your web.config:
激活元数据发布,以便找到您的服务,为此,将以下行为添加到您的web.config:
<system.serviceModel> <services> <service name="WcfService1.MyService"> <endpoint binding="basicHttpBinding" bindingConfiguration="" contract="WcfService1.IMyService" BehaviorConfiguration="MyServiceBehaviors" /> </service> </services> </system.serviceModel> <behaviors> <serviceBehaviors> <behavior name="MyServiceBehaviors" > <serviceMetadata httpGetEnabled="true" /> </behavior> </serviceBehaviors> </behaviors>
Now you should be able to run your project and get a metadata description page of your service within the browser, this info can be used by clients to find the service and generate a proxy of the service:
现在您应该可以在浏览器中运行您的项目并获得服务的元数据描述页面,客户可以使用此信息查找服务并生成服务的代理:
The Client
客户端
- Delete any existing service references from your project.
- 从项目中删除任何现有的服务引用。
- Right click on your project name then in "Add Service Reference", input your service address and click on "Go", if everything went all right you should see your service in the Service Window:
- 右键单击项目名称,然后在“添加服务引用”中,输入您的服务地址并点击“Go”,如果一切正常,您应该在服务窗口中看到您的服务:
-
Try to generate the proxy by finishing the wizard, rebuild your project and try it. If you still have the same problem, delete the generated reference and repeat points 1 and 2 and then:
尝试通过完成向导来生成代理,重新构建项目并尝试它。如果您仍然有同样的问题,删除生成的引用,重复点1和2,然后:
-
Click on "Advanced" and uncheck "Reuse types in referenced assemblies":
点击“高级”,取消“引用程序集中的重用类型”:
Then finish the wizard and compile.
然后完成向导并编译。
Hopefully, everything should work now!!!
希望现在一切都顺利!!
#2
1
I may have a similar setup as yours. In my case, I have both the STS and a service that is called by whoever wants a token. This is what you have, right?
我可能有一个类似你的设置。在我的例子中,我有STS和一个服务,任何需要令牌的人都可以调用它。这就是你所拥有的,对吧?
In the Web.config for the actual STS I have:
在Web。我的实际STS配置:
<bindings>
<ws2007HttpBinding>
<binding name="ws2007HttpBindingConfiguration">
<security mode="TransportWithMessageCredential">
<message establishSecurityContext="false" clientCredentialType="Certificate"/>
</security>
</binding>
</ws2007HttpBinding>
</bindings>
<services>
<service name="System.ServiceModel.Security.WSTrustServiceContract" behaviorConfiguration="STSBehavior">
<endpoint address="IWSTrust13" binding="ws2007HttpBinding" bindingConfiguration="ws2007HttpBindingConfiguration" contract="System.ServiceModel.Security.IWSTrust13SyncContract" name="STSWCF"/>
<endpoint address="mex" binding="mexHttpsBinding" contract="IMetadataExchange"/>
</service>
</services>
And in the Web.config for the service I have:
和网络。我拥有的服务配置:
<protocolMapping>
<!-- We want to use ws2007FederationHttpBinding over HTTPS -->
<add scheme="https" binding="ws2007FederationHttpBinding" bindingConfiguration="ws2007FederationHttpBindingConfiguration"/>
</protocolMapping>
<bindings>
<ws2007FederationHttpBinding>
<binding name="ws2007FederationHttpBindingConfiguration">
<!-- We expect a bearer token sent through an HTTPS channel -->
<security mode="TransportWithMessageCredential">
<message establishSecurityContext="false">
<issuerMetadata address="https://localhost/Identity.STS.WCF/Service.svc/mex"/>
</message>
</security>
</binding>
</ws2007FederationHttpBinding>
</bindings>
<services>
<service name="Identity.Auth.WCF.Service" behaviorConfiguration="STSBehavior">
<endpoint address="https://localhost/Identity.Auth.WCF/Service.svc" binding="ws2007FederationHttpBinding" bindingConfiguration="ws2007FederationHttpBindingConfiguration" contract="Identity.Auth.WCF.IService" name="Identity.Auth.WCF"/>
</service>
</services>
Also, it does work for me here, even though I do get the same IntelliSense error as you, and in the very same spot.
同样,它在这里对我也适用,尽管我确实得到了和你们一样的智能感知错误,在同样的位置。