English 中文(简体)
可在WCF REST 4中作为回复格式之一退还超文本。
原标题:Is it possible in WCF REST 4 to return HTML as one of the response formats
  • 时间:2012-05-09 15:19:53
  •  标签:
  • c#
  • wcf
  • rest

我写的是一份服务,打算供多个打电话者使用,包括无法接收或教化Xoma或JN的人。

我知道它有可能从使用原始溪流的服务对策中退回超文本,但我希望能够做的是,根据客户的接受方-Type头盔,归还XML、JSON或超文本之一。

我可以用精炼的URLs来做到这一点,但这正在取代一个已经明确界定的亚特兰大的系统。

是否有任何实例可提供,或者任何人都知道需要扩大管道的哪些部分?

(增编): 我已经知道自动选用物,并且能够选用,但我希望从一个终点支持所有三个(或更多的)形式(超额、初等、十多种语文等)。

最佳回答

是的,这是可能的。 但是,你需要创建一个新的message Formatter,其中知道如何在《刑法》的类型(行动反应)和“超文本”之间转换。 这样做的最简单办法是以新的格式包罗原始格式,这样,当你收到对<条码>Accept:文本/html的要求的答复时,你使用你的逻辑,但对于其他请求,你使用原格式。

The formatter doesn t have a way to get access to the incoming requests, though, so we can use a message inspector to provide that as well.

下面的守则表明,这种格式/检查机可能实施。

public class StackOverflow_10519075
{
    [DataContract(Name = "Person", Namespace = "")]
    public class Person
    {
        [DataMember]
        public string Name { get; set; }
        [DataMember]
        public int Age { get; set; }
    }
    [ServiceContract]
    public interface ITest
    {
        [WebGet]
        Person GetPerson();
    }
    public class Service : ITest
    {
        public Person GetPerson()
        {
            return new Person { Name = "John Doe", Age = 33 };
        }
    }
    public class MyHtmlAwareFormatter : IDispatchMessageFormatter
    {
        IDispatchMessageFormatter original;
        public MyHtmlAwareFormatter(IDispatchMessageFormatter original)
        {
            this.original = original;
        }

        public void DeserializeRequest(Message message, object[] parameters)
        {
            this.original.DeserializeRequest(message, parameters);
        }

        public Message SerializeReply(MessageVersion messageVersion, object[] parameters, object result)
        {
            MyUseHtmlExtension useHtml = OperationContext.Current.Extensions.Find<MyUseHtmlExtension>();
            if (useHtml != null && useHtml.UseHtmlResponse)
            {
                StringBuilder sb = new StringBuilder();
                sb.AppendLine("<html><head><title>Result of " + useHtml.OperationName + "</title></head>");
                sb.AppendLine("<body><h1>Result of " + useHtml.OperationName + "</h1>");
                sb.AppendLine("<p><b>" + result.GetType().FullName + "</b></p>");
                sb.AppendLine("<ul>");
                foreach (var prop in result.GetType().GetProperties())
                {
                    string line = string.Format("{0}: {1}", prop.Name, prop.GetValue(result, null));
                    sb.AppendLine("<li>" + line + "</li>");
                }
                sb.AppendLine("</ul></body></html>");
                byte[] bytes = Encoding.UTF8.GetBytes(sb.ToString());
                Message reply = Message.CreateMessage(messageVersion, null, new RawBodyWriter(bytes));
                reply.Properties.Add(WebBodyFormatMessageProperty.Name, new WebBodyFormatMessageProperty(WebContentFormat.Raw));
                HttpResponseMessageProperty httpResp = new HttpResponseMessageProperty();
                reply.Properties.Add(HttpResponseMessageProperty.Name, httpResp);
                httpResp.Headers[HttpResponseHeader.ContentType] = "text/html";
                return reply;
            }
            else
            {
                return original.SerializeReply(messageVersion, parameters, result);
            }
        }

        class RawBodyWriter : BodyWriter
        {
            private byte[] bytes;

            public RawBodyWriter(byte[] bytes)
                : base(true)
            {
                this.bytes = bytes;
            }

            protected override void OnWriteBodyContents(XmlDictionaryWriter writer)
            {
                writer.WriteStartElement("Binary");
                writer.WriteBase64(this.bytes, 0, this.bytes.Length);
                writer.WriteEndElement();
            }
        }
    }
    public class MyHtmlAwareInspector : IDispatchMessageInspector
    {
        public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
        {
            HttpRequestMessageProperty httpRequest = (HttpRequestMessageProperty)request.Properties[HttpRequestMessageProperty.Name];
            string accept = httpRequest.Headers[HttpRequestHeader.Accept];
            string operationName = request.Properties[WebHttpDispatchOperationSelector.HttpOperationNamePropertyName] as string;
            if (accept == "text/html")
            {
                OperationContext.Current.Extensions.Add(new MyUseHtmlExtension { UseHtmlResponse = true, OperationName = operationName });
            }

            return null;
        }

        public void BeforeSendReply(ref Message reply, object correlationState)
        {
        }
    }
    class MyUseHtmlExtension : IExtension<OperationContext>
    {
        public void Attach(OperationContext owner) { }
        public void Detach(OperationContext owner) { }
        public bool UseHtmlResponse { get; set; }
        public string OperationName { get; set; }
    }
    public class MyHtmlAwareEndpointBehavior : IEndpointBehavior
    {
        public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
        {
        }

        public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
        {
        }

        public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
        {
            endpointDispatcher.DispatchRuntime.MessageInspectors.Add(new MyHtmlAwareInspector());
            foreach (DispatchOperation operation in endpointDispatcher.DispatchRuntime.Operations)
            {
                operation.Formatter = new MyHtmlAwareFormatter(operation.Formatter);
            }
        }

        public void Validate(ServiceEndpoint endpoint)
        {
        }
    }
    public static void Test()
    {
        string baseAddress = "http://" + Environment.MachineName + ":8000/Service";
        ServiceHost host = new ServiceHost(typeof(Service), new Uri(baseAddress));
        var endpoint = host.AddServiceEndpoint(typeof(ITest), new WebHttpBinding(), "");
        endpoint.Behaviors.Add(new WebHttpBehavior { AutomaticFormatSelectionEnabled = true });
        endpoint.Behaviors.Add(new MyHtmlAwareEndpointBehavior());
        host.Open();
        Console.WriteLine("Host opened");

        WebClient c;

        c = new WebClient();
        c.Headers[HttpRequestHeader.Accept] = "application/json";
        Console.WriteLine(c.DownloadString(baseAddress + "/GetPerson"));
        Console.WriteLine();

        c = new WebClient();
        c.Headers[HttpRequestHeader.Accept] = "text/xml";
        Console.WriteLine(c.DownloadString(baseAddress + "/GetPerson"));
        Console.WriteLine();

        c = new WebClient();
        c.Headers[HttpRequestHeader.Accept] = "text/html";
        Console.WriteLine(c.DownloadString(baseAddress + "/GetPerson"));
        Console.WriteLine();

        Console.Write("Press ENTER to close the host");
        Console.ReadLine();
        host.Close();
    }
}
问题回答

暂无回答




相关问题
Anyone feel like passing it forward?

I m the only developer in my company, and am getting along well as an autodidact, but I know I m missing out on the education one gets from working with and having code reviewed by more senior devs. ...

NSArray s, Primitive types and Boxing Oh My!

I m pretty new to the Objective-C world and I have a long history with .net/C# so naturally I m inclined to use my C# wits. Now here s the question: I feel really inclined to create some type of ...

C# Marshal / Pinvoke CBitmap?

I cannot figure out how to marshal a C++ CBitmap to a C# Bitmap or Image class. My import looks like this: [DllImport(@"test.dll", CharSet = CharSet.Unicode)] public static extern IntPtr ...

How to Use Ghostscript DLL to convert PDF to PDF/A

How to user GhostScript DLL to convert PDF to PDF/A. I know I kind of have to call the exported function of gsdll32.dll whose name is gsapi_init_with_args, but how do i pass the right arguments? BTW, ...

Linqy no matchy

Maybe it s something I m doing wrong. I m just learning Linq because I m bored. And so far so good. I made a little program and it basically just outputs all matches (foreach) into a label control. ...

热门标签