请帮助。我试图使用HttpWebRequest访问暴露给服务总线中继端点的WCF服务。
我通过OAuth WRAP协议从ACS成功获得了令牌。使用该令牌作为请求头中的授权,我创建了一个WebRequest,用于与WCF服务通信,其端点配置为WebHttpRelayBinding,WCF服务方法应用OperationContractAttribute和WebGetAttribute。
当我运行客户端应用程序时,出现以下错误:
带有To的消息 'https://namespace.servicebus.windows.net/Student/GetInfo/GetStudentInfo/1' 由于AddressFilter不匹配,无法在接收器处理 在EndpointDispatcher。检查发件人和收件人 EndpointAddresses同意。
我用Google搜索并找到了将以下属性应用于服务类的建议:
[ServiceBehavior(AddressFilterMode = AddressFilterMode.Any)]
虽然这解决了以前的错误,但现在客户端应用程序最终出现以下错误:
无法在接收方处理具有Action'GET'的消息 到EndpointDispatcher的ContractFilter不匹配。这可能是 因为合同不匹配(两者之间不匹配的行为) 发件人和收件人)或发件人之间的绑定/安全性不匹配 和接收器。检查发件人和收件人是否一样 合同和相同的约束(包括安全要求,例如 消息,传输,无)。
我认为我在WCF服务方面遗漏了一些东西。共享客户端和服务代码以供审核。
WCF服务代码:
[ServiceContract]
interface IStudentInfo
{
[OperationContract]
[WebGet(ResponseFormat = WebMessageFormat.Xml, UriTemplate = "/GetStudentInfo/{studentId}")]
string GetStudentInfo(string studentId);
}
[ServiceBehavior(AddressFilterMode = AddressFilterMode.Any)]
private class StudentInfo : IStudentInfo
{
string IStudentInfo.GetStudentInfo(string studentId)
{
string returnString = null;
// .....
return returnString;
}
}
public void Run()
{
Console.WriteLine("LISTENER");
Console.WriteLine("========");
string serviceNamespace = "namespace";
string issuerName = "owner";
string issuerKey = "key";
string servicePath = "Student/GetInfo";
ServiceHost sh = new ServiceHost(typeof(StudentInfo));
// Binding
WebHttpRelayBinding binding2 = new WebHttpRelayBinding();
Uri uri = ServiceBusEnvironment.CreateServiceUri(Uri.UriSchemeHttps, serviceNamespace, servicePath);
Console.WriteLine("Service Uri: " + uri);
Console.WriteLine();
sh.AddServiceEndpoint(typeof(IStudentInfo), binding2, uri);
// Create the ServiceRegistrySettings behavior for the endpoint.
var serviceRegistrySettings = new ServiceRegistrySettings(DiscoveryType.Public);
// Create the shared secret credentials object for the endpoint matching the
// Azure access control services issuer
var sharedSecretServiceBusCredential = new TransportClientEndpointBehavior()
{
TokenProvider = TokenProvider.CreateSharedSecretTokenProvider(issuerName, issuerKey)
};
// Add the service bus credentials to all endpoints specified in configuration.
foreach (var endpoint in sh.Description.Endpoints)
{
endpoint.Behaviors.Add(serviceRegistrySettings);
endpoint.Behaviors.Add(sharedSecretServiceBusCredential);
}
sh.Open();
Console.WriteLine("Press ENTER to close");
Console.ReadLine();
sh.Close();
}
服务消费代码:
static void Main(string[] args)
{
var studentId = "1";
string _token = GetToken();
Console.WriteLine(_token);
// Create and configure the Request
var httpWebRequest = (HttpWebRequest)WebRequest.Create("https://namespace.servicebus.windows.net/Student/GetInfo/GetStudentInfo/" + studentId);
httpWebRequest.ContentType = "text/json";
httpWebRequest.Method = "GET";
httpWebRequest.Headers.Add(HttpRequestHeader.Authorization, string.Format("WRAP access_token=\"{0}\"", _token));
// Get the response using the Request
HttpWebResponse response = httpWebRequest.GetResponse() as HttpWebResponse;
// Read the stream from the response object
Stream stream = response.GetResponseStream();
StreamReader reader = new StreamReader(stream);
// Read the result from the stream reader
string result = reader.ReadToEnd();
Console.WriteLine("Result: " + result);
Console.ReadLine();
}
static string GetToken()
{
string base_address = string.Format("https://namespace-sb.accesscontrol.windows.net");
string wrap_name = "owner";
string wrap_password = "key";
string wrap_scope = "http://namespace.servicebus.windows.net/";
WebClient client = new WebClient();
client.BaseAddress = base_address;
NameValueCollection values = new NameValueCollection();
values.Add("wrap_name", wrap_name);
values.Add("wrap_password", wrap_password);
values.Add("wrap_scope", wrap_scope);
byte[] responseBytes = client.UploadValues("WRAPv0.9", "POST", values);
string response = Encoding.UTF8.GetString(responseBytes);
string token = response.Split('&')
.Single(value => value.StartsWith("wrap_access_token="))
.Split('=')[1];
string _token = HttpUtility.UrlDecode(token);
return _token;
}
答案 0 :(得分:1)
最后它完成了!
我错过了一个WebHttpBehavior
到端点,这是将WCF服务公开为REST端点所必需的。
endpoint.Behaviors.Add(new WebHttpBehavior());
或者我可以在WebServiceHost
而不是'ServiceHost'中托管服务,以使REST绑定起作用。
WebServiceHost sh = new WebServiceHost(typeof(StudentInfo));