简体   繁体   English

.NET WCF RIA +服务; 能给我全部吗

[英].NET WCF RIA + Services; Can I have it all?

What I'd like to have is "regular" WCF service calls responding on my root URL as well as the regular RIA stuff. 我想要的是在我的根URL以及常规RIA上响应的“常规” WCF服务调用。 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. RIA的工作原理包括ODATA JSON和SOAP,但是传统的Web服务不想运行根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: 访问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>

Can anyone see what I'm missing? 谁能看到我所缺少的吗?

Thanks in advance! 提前致谢!

For me, I just needed to return raw strings on that endpoint so I implemented my own HttpBehavior and DispatchFormatter as such: 对我来说,我只需要在该终结点上返回原始字符串,所以我实现了自己的HttpBehavior和DispatchFormatter,如下所示:

    public class WebHttpBehaviorEx : WebHttpBehavior
    {
        protected override IDispatchMessageFormatter GetReplyDispatchFormatter(OperationDescription operationDescription, ServiceEndpoint endpoint)
        {
            return new DynamicFormatter();
        }
    }

    public class DynamicFormatter : IDispatchMessageFormatter
    {
        public void DeserializeRequest(Message message, object[] parameters)
        {
            throw new NotImplementedException();
        }

        public Message SerializeReply(MessageVersion messageVersion, object[] parameters, object result)
        {
            return WebOperationContext.Current.CreateTextResponse((result ?? string.Empty).ToString());
        }
    }

and changed 并改变了

ep.Behaviors.Add(new WebHttpBehavior());

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM