使用CORS Message Inspector的XML序列化未使用数据协定序列化 [英] XML Serialization using CORS Message Inspector is not using the Data Contract Serialization

查看:44
本文介绍了使用CORS Message Inspector的XML序列化未使用数据协定序列化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们已经实现了当前的REST服务,该服务会返回类似以下项的列表:

We have a current REST service implemented that returns a list of items like this:

< Items xmlns ="http://schemas.datacontract.org/2004/07/Mns.DataProvider" xmlns:i ="http://www.w3.org/2001/XMLSchema-instance">
< Item i:type =" CalculatedItemInfo">
< StartDate> 2017-05-01T00:00:00</StartDate>
< StartValue> 0</StartValue>
< Type>绝对</Type>
<单位>无</单位>
< UserKey1> 1</UserKey1>
< UserKey2/>
< UserKey3/>
<计算/>
</Item>
< Item i:type =" StandardItemInfo">
<名称> AW特警|威尔兰|子集水区| LCALC</名称>
<计算/>
</Item>

<Items xmlns="http://schemas.datacontract.org/2004/07/Mns.DataProvider" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<Item i:type="CalculatedItemInfo">
<StartDate>2017-05-01T00:00:00</StartDate>
<StartValue>0</StartValue>
<Type>Absolute</Type>
<Units>None</Units>
<UserKey1>1</UserKey1>
<UserKey2/>
<UserKey3/>
<Calculation/>
</Item>
<Item i:type="StandardItemInfo">
<Name>AW Swat|Welland|Subcatchment|LCALC</Name>
<Calculation/>
</Item>

列表上有一个DataContractAttribute,如下所示:

The list has a DataContractAttribute on it as follows:

    [CollectionDataContract(Name =" Items"))]
   公共类BaseItemInfos:List< BaseItemInfo>
    {
    }

    [CollectionDataContract(Name = "Items")]
    public class BaseItemInfos : List<BaseItemInfo>
    {
    }

一切正常.我现在添加了一个CORS消息检查器,因为我们需要支持相当标准的CORS:

which all works well. I have now added a CORS message inspector as we need to support CORS which is fairly standard:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Dispatcher;
using System.ServiceModel.Web;
using System.Text;

namespace Mns.WebService
{
    public class CorsMessageInspector : IDispatchMessageInspector
    {
        private static readonly HashSet<string> s_helpPageUris = new HashSet<string>(new string[] { "GetHelpPage", "GetOperationHelpPage" }, StringComparer.OrdinalIgnoreCase);

        private const string BasicPrefix = "basic ";
        private static readonly int s_basicPrefixLength = BasicPrefix.Length;
        private readonly bool m_enforceBasicAuthentication;

        public CorsMessageInspector(bool enforceBasicAuthentication)
        {
            m_enforceBasicAuthentication = enforceBasicAuthentication;
        }

        public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
        {
            // Check if the client sent a preflight request for CORS
            HttpRequestMessageProperty httpRequest = request.Properties[HttpRequestMessageProperty.Name] as HttpRequestMessageProperty;
            if (httpRequest == null) return null;

            string origin = httpRequest.Headers["Origin"];
            if (!String.IsNullOrEmpty(origin)) OperationContext.Current.Extensions.Add(new CorsOperationContext(origin));

            if (String.Equals(httpRequest.Method, "options", StringComparison.OrdinalIgnoreCase))
                OperationContext.Current.Extensions.Add(new PreflightOperationContext(httpRequest.Headers["Access-Control-Request-Headers"])); // CORS Preflight
            else if (m_enforceBasicAuthentication)
            {
                if (PasswordValidator == null) throw new WebFaultException<string>("Access denied", HttpStatusCode.Unauthorized);

                // Allow help pages through without authentication
                if ((WebOperationContext.Current.IncomingRequest.UriTemplateMatch != null) && s_helpPageUris.Contains(WebOperationContext.Current.IncomingRequest.UriTemplateMatch.Data.ToString())) return null;

                // If not then authorize
                string authorizationHeader = WebOperationContext.Current.IncomingRequest.Headers[HttpRequestHeader.Authorization];
                if (!String.IsNullOrEmpty(authorizationHeader))
                {
                    int basicIndex = authorizationHeader.IndexOf(BasicPrefix, StringComparison.OrdinalIgnoreCase);
                    if (basicIndex != -1)
                    {
                        string encodedUserNamePassword = authorizationHeader.Substring(basicIndex + s_basicPrefixLength);
                        if (!String.IsNullOrEmpty(encodedUserNamePassword))
                        {
                            string userNamePassword = null;
                            try
                            {
                                userNamePassword = ASCIIEncoding.ASCII.GetString(Convert.FromBase64String(encodedUserNamePassword));
                            }
                            catch (FormatException) { }
                            catch (ArgumentException) { }

                            if (!String.IsNullOrEmpty(userNamePassword))
                            {
                                int colonIndex = userNamePassword.IndexOf(":", StringComparison.OrdinalIgnoreCase);
                                if (colonIndex != -1)
                                {
                                    string userName = userNamePassword.Substring(0, colonIndex);
                                    string password = userNamePassword.Substring(colonIndex + 1);

                                    if (!String.IsNullOrEmpty(userName))
                                    {
                                        PasswordValidator.Validate(userName, password);
                                        AuthorizationOperationContext.Current.UserName = userName;
                                        AuthorizationOperationContext.Current.ContentType = httpRequest.Headers["Content-Type"];

                                        return null;
                                    }
                                }
                            }
                        }
                    }
                }

                WebOperationContext.Current.OutgoingResponse.Headers.Add("WWW-Authenticate", @"Basic realm=""MCE""");
                throw new WebFaultException<string>("Access denied", HttpStatusCode.Unauthorized);
            }

            return null;
        }

        public void BeforeSendReply(ref Message reply, object correlationState)
        {
            PreflightOperationContext preflightContext = OperationContext.Current.Extensions.Find<PreflightOperationContext>();
            HttpResponseMessageProperty httpHeader = null;

            if (preflightContext != null)
            {
                httpHeader = new HttpResponseMessageProperty() { StatusCode = HttpStatusCode.OK };
                reply.Properties[HttpResponseMessageProperty.Name] = httpHeader;
            }
            else if (reply != null)
            {
                httpHeader = reply.Properties[HttpResponseMessageProperty.Name] as HttpResponseMessageProperty;
                httpHeader.Headers["Content-Type"] = AuthorizationOperationContext.Current.ContentType;
                reply.Properties[WebBodyFormatMessageProperty.Name] = new WebBodyFormatMessageProperty(AuthorizationOperationContext.Current.BodyFormat);
            }
 
            if (httpHeader != null)
            {
                CorsOperationContext corsContext = OperationContext.Current.Extensions.Find<CorsOperationContext>();

                WebHeaderCollection headers = httpHeader.Headers;

                if (preflightContext != null)
                {
                    string requestedHeaders = preflightContext.RequestedHeaders;
                    if (!String.IsNullOrEmpty(requestedHeaders)) requestedHeaders += ", ";
                    requestedHeaders += "content-Type, accept, authorization";

                    headers.Add("Access-Control-Allow-Methods", "POST, GET, OPTIONS");
                    headers.Add("Access-Control-Allow-Headers", requestedHeaders);
                }

                headers.Add("Access-Control-Allow-Credentials", "true");
                headers.Add("Access-Control-Allow-Origin", (corsContext != null) ? corsContext.Origin : "*");
            }
        }

        public static PasswordValidator PasswordValidator { get; set; }
    }
}

现在我们使用的是CORS端点,XML返回如下:

Now we are using a CORS end point the XML is coming back as follows:

< root   数组" >

推荐答案

我认为需要做的是使用DataContractSerializer重写消息创建.

I think what needs to be done is the message creation needs to be overridden to use the DataContractSerializer. 

如何使用消息检查器覆盖它?

How can I override this using a message inspector?

谢谢

伊恩


这篇关于使用CORS Message Inspector的XML序列化未使用数据协定序列化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆