.NET WCF RIA +服务;我可以拥有这一切吗?
我想要的是在我的根 URL 上响应的“常规”WCF 服务调用以及常规 RIA 内容。看似简单,但做起来却有点痛苦。 RIA 的工作包括 ODATA JSON 和 SOAP,但传统的 Web 服务不想运行根 URL。
请参阅以下代码:
using System;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.ServiceModel;
using System.ServiceModel.Activation;
using System.ServiceModel.Channels;
using System.ServiceModel.Description;
using System.ServiceModel.DomainServices.Hosting;
using System.ServiceModel.DomainServices.Server;
using System.ServiceModel.Web;
using Microsoft.ServiceModel.DomainServices.Hosting;
namespace ConsoleApplication1
{
public partial class Program
{
[EnableClientAccess, ServiceContract]
public class TestDomainService : DomainService
{
[Query(IsDefault = true)]
public IQueryable<Foo> GetAllFoos()
{
return new Foo[] { new Foo { Id = 1, Name = "Jonathan" } }.AsQueryable();
}
[WebInvoke(Method="GET"), OperationContract]
public Message Test()
{
return WebOperationContext.Current.CreateTextResponse("Test");
}
}
public class Foo
{
[Key]
public int Id { get; set; }
public string Name { get; set; }
}
static void Main(string[] args)
{
var baseUri = new Uri("http://localhost:999");
var svc = new DomainServiceHost(typeof(TestDomainService), new Uri[] { baseUri });
svc.Description.Behaviors.RemoveAll<AspNetCompatibilityRequirementsAttribute>();
svc.Description.Behaviors.OfType<ServiceMetadataBehavior>().First().HttpGetEnabled = true;
var svcDescription = DomainServiceDescription.GetDescription(typeof(TestDomainService));
var odataEndpoints = new ODataEndpointFactory().CreateEndpoints(svcDescription, svc);
var soapEndpoints = new SoapXmlEndpointFactory().CreateEndpoints(svcDescription, svc);
var jsonEndpoints = new JsonEndpointFactory().CreateEndpoints(svcDescription, svc);
var odata = odataEndpoints.First();
odata.Contract.Namespace = new Uri(baseUri, "ODATA").ToString();
odata.Address = new System.ServiceModel.EndpointAddress(new Uri(baseUri, "ODATA"));
var soap = soapEndpoints.First();
soap.Contract.Namespace = new Uri(baseUri, "SOAP").ToString();
soap.Address = new System.ServiceModel.EndpointAddress(new Uri(baseUri, "SOAP"));
var json = jsonEndpoints.First();
json.Contract.Namespace = new Uri(baseUri, "JSON").ToString();
json.Address = new System.ServiceModel.EndpointAddress(new Uri(baseUri, "JSON"));
var ep = new ServiceEndpoint(svc.Description.Endpoints[0].Contract, new WebHttpBinding(), new EndpointAddress(baseUri));
ep.Behaviors.Add(new WebHttpBehavior());
var cd = ContractDescription.GetContract(typeof(TestDomainService));
foreach (var op in cd.Operations)
{
if (ep.Contract.Operations.Any(o => o.Name == op.Name) == false)
{
ep.Contract.Operations.Add(op);
}
}
svc.Description.Endpoints.Add(ep);
svc.Description.Endpoints.Add(odata);
svc.Description.Endpoints.Add(soap);
svc.Description.Endpoints.Add(json);
svc.Open();
foreach (var endpoint in svc.Description.Endpoints)
{
Console.WriteLine("Domain service started on: {0}", endpoint.Address.Uri);
}
Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
}
}
访问 http://localhost:999/Test 应该会导致只显示 Test,但实际上我得到:
<Fault xmlns="http://schemas.microsoft.com/ws/2005/05/envelope/none">
<Code>
<Value>Sender</Value>
<Subcode>
<Value xmlns:a="http://schemas.microsoft.com/ws/2005/05/addressing/none">a:ActionNotSupported</Value>
</Subcode>
</Code>
<Reason>
<Text xml:lang="en-US">The message with Action '' cannot be processed at the receiver, due to a ContractFilter mismatch at the EndpointDispatcher. This may be because of either a contract mismatch (mismatched Actions between sender and receiver) or a binding/security mismatch between the sender and the receiver. Check that sender and receiver have the same contract and the same binding (including security requirements, e.g. Message, Transport, None).</Text>
</Reason>
</Fault>
有人能看到我错过了什么吗?
提前致谢!
What I'd like to have is "regular" WCF service calls responding on my root URL as well as the regular RIA stuff. Seems simple, but is turning out to be a bit of a pain. The RIA stuff works including ODATA JSON and SOAP, but the traditional web services doesn't want to run off the root URL.
See the following code:
using System;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.ServiceModel;
using System.ServiceModel.Activation;
using System.ServiceModel.Channels;
using System.ServiceModel.Description;
using System.ServiceModel.DomainServices.Hosting;
using System.ServiceModel.DomainServices.Server;
using System.ServiceModel.Web;
using Microsoft.ServiceModel.DomainServices.Hosting;
namespace ConsoleApplication1
{
public partial class Program
{
[EnableClientAccess, ServiceContract]
public class TestDomainService : DomainService
{
[Query(IsDefault = true)]
public IQueryable<Foo> GetAllFoos()
{
return new Foo[] { new Foo { Id = 1, Name = "Jonathan" } }.AsQueryable();
}
[WebInvoke(Method="GET"), OperationContract]
public Message Test()
{
return WebOperationContext.Current.CreateTextResponse("Test");
}
}
public class Foo
{
[Key]
public int Id { get; set; }
public string Name { get; set; }
}
static void Main(string[] args)
{
var baseUri = new Uri("http://localhost:999");
var svc = new DomainServiceHost(typeof(TestDomainService), new Uri[] { baseUri });
svc.Description.Behaviors.RemoveAll<AspNetCompatibilityRequirementsAttribute>();
svc.Description.Behaviors.OfType<ServiceMetadataBehavior>().First().HttpGetEnabled = true;
var svcDescription = DomainServiceDescription.GetDescription(typeof(TestDomainService));
var odataEndpoints = new ODataEndpointFactory().CreateEndpoints(svcDescription, svc);
var soapEndpoints = new SoapXmlEndpointFactory().CreateEndpoints(svcDescription, svc);
var jsonEndpoints = new JsonEndpointFactory().CreateEndpoints(svcDescription, svc);
var odata = odataEndpoints.First();
odata.Contract.Namespace = new Uri(baseUri, "ODATA").ToString();
odata.Address = new System.ServiceModel.EndpointAddress(new Uri(baseUri, "ODATA"));
var soap = soapEndpoints.First();
soap.Contract.Namespace = new Uri(baseUri, "SOAP").ToString();
soap.Address = new System.ServiceModel.EndpointAddress(new Uri(baseUri, "SOAP"));
var json = jsonEndpoints.First();
json.Contract.Namespace = new Uri(baseUri, "JSON").ToString();
json.Address = new System.ServiceModel.EndpointAddress(new Uri(baseUri, "JSON"));
var ep = new ServiceEndpoint(svc.Description.Endpoints[0].Contract, new WebHttpBinding(), new EndpointAddress(baseUri));
ep.Behaviors.Add(new WebHttpBehavior());
var cd = ContractDescription.GetContract(typeof(TestDomainService));
foreach (var op in cd.Operations)
{
if (ep.Contract.Operations.Any(o => o.Name == op.Name) == false)
{
ep.Contract.Operations.Add(op);
}
}
svc.Description.Endpoints.Add(ep);
svc.Description.Endpoints.Add(odata);
svc.Description.Endpoints.Add(soap);
svc.Description.Endpoints.Add(json);
svc.Open();
foreach (var endpoint in svc.Description.Endpoints)
{
Console.WriteLine("Domain service started on: {0}", endpoint.Address.Uri);
}
Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
}
}
Accessing http://localhost:999/Test should result in just Test being displayed, but instead I get:
<Fault xmlns="http://schemas.microsoft.com/ws/2005/05/envelope/none">
<Code>
<Value>Sender</Value>
<Subcode>
<Value xmlns:a="http://schemas.microsoft.com/ws/2005/05/addressing/none">a:ActionNotSupported</Value>
</Subcode>
</Code>
<Reason>
<Text xml:lang="en-US">The message with Action '' cannot be processed at the receiver, due to a ContractFilter mismatch at the EndpointDispatcher. This may be because of either a contract mismatch (mismatched Actions between sender and receiver) or a binding/security mismatch between the sender and the receiver. Check that sender and receiver have the same contract and the same binding (including security requirements, e.g. Message, Transport, None).</Text>
</Reason>
</Fault>
Can anyone see what I'm missing?
Thanks in advance!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
对我来说,我只需要在该端点上返回原始字符串,因此我实现了自己的 HttpBehavior 和 DispatchFormatter:
并进行了更改
For me, I just needed to return raw strings on that endpoint so I implemented my own HttpBehavior and DispatchFormatter as such:
and changed