How to pass XML as POST to an ActionResult in ASP MVC .NET

后端 未结 7 834
[愿得一人]
[愿得一人] 2020-12-15 10:05

I am trying to provide a simple RESTful API to my ASP MVC project. I will not have control of the clients of this API, they will be passing an XML via a POST method that wi

7条回答
  •  隐瞒了意图╮
    2020-12-15 10:23

    IMO the best way to accomplish this is to write a custom value provider, this is a factory that handles the mapping of the request to the forms dictionary. You just inherit from ValueProviderFactory and handle the request if it is of type “text/xml” or “application/xml.”

    More Info:

    Phil Haack

    My blog

    MSDN

    protected override void OnApplicationStarted()
    {
        AreaRegistration.RegisterAllAreas();
    
        RegisterRoutes(RouteTable.Routes);
    
        ValueProviderFactories.Factories.Add(new JsonValueProviderFactory());
        ValueProviderFactories.Factories.Add(new XmlValueProviderFactory());
    }
    

    XmlValueProviderFactory

    using System;
    using System.Collections.Generic;
    using System.Globalization;
    using System.Web.Mvc;
    using System.Xml;
    using System.Xml.Linq;
    
    public class XmlValueProviderFactory : ValueProviderFactory
    {
    
        public override IValueProvider GetValueProvider(ControllerContext controllerContext)
        {
            var deserializedXml = GetDeserializedXml(controllerContext);
    
            if (deserializedXml == null) return null;
    
            var backingStore = new Dictionary(StringComparer.OrdinalIgnoreCase);
    
            AddToBackingStore(backingStore, string.Empty, deserializedXml.Root);
    
            return new DictionaryValueProvider(backingStore, CultureInfo.CurrentCulture);
    
        }
    
        private static void AddToBackingStore(Dictionary backingStore, string prefix, XElement xmlDoc)
        {
            // Check the keys to see if this is an array or an object
            var uniqueElements = new List();
            var totalElments = 0;
            foreach (XElement element in xmlDoc.Elements())
            {
                if (!uniqueElements.Contains(element.Name.LocalName))
                    uniqueElements.Add(element.Name.LocalName);
                totalElments++;
            }
    
            var isArray = (uniqueElements.Count == 1 && totalElments > 1);
    
    
            // Add the elements to the backing store
            var elementCount = 0;
            foreach (XElement element in xmlDoc.Elements())
            {
                if (element.HasElements)
                {
                    if (isArray)
                        AddToBackingStore(backingStore, MakeArrayKey(prefix, elementCount), element);
                    else
                        AddToBackingStore(backingStore, MakePropertyKey(prefix, element.Name.LocalName), element);
                }
                else
                {
                    backingStore.Add(MakePropertyKey(prefix, element.Name.LocalName), element.Value);
                }
                elementCount++;
            }
        }
    
    
        private static string MakeArrayKey(string prefix, int index)
        {
            return prefix + "[" + index.ToString(CultureInfo.InvariantCulture) + "]";
        }
    
        private static string MakePropertyKey(string prefix, string propertyName)
        {
            if (!string.IsNullOrEmpty(prefix))
                return prefix + "." + propertyName;
            return propertyName;
        }
    
        private XDocument GetDeserializedXml(ControllerContext controllerContext)
        {
            var contentType = controllerContext.HttpContext.Request.ContentType;
            if (!contentType.StartsWith("text/xml", StringComparison.OrdinalIgnoreCase) &&
                !contentType.StartsWith("application/xml", StringComparison.OrdinalIgnoreCase))
                return null;
    
            XDocument xml;
            try
            {
                var xmlReader = new XmlTextReader(controllerContext.HttpContext.Request.InputStream);
                xml = XDocument.Load(xmlReader);
            }
            catch (Exception)
            {
                return null;
            }
    
            if (xml.FirstNode == null)//no xml.
                return null;
    
            return xml;
        }
    }
    
        

    提交回复
    热议问题