Come POST XML in un Controller MVC? (invece di chiave/valore)

Utilizzando il Violinista posso passare nel corpo

someXml=ThisShouldBeXml

e poi il controller

    [HttpPost]
    public ActionResult Test(object someXml)
    {
        return Json(someXml);
    }

ottiene questo dato come una stringa

Come posso ottenere il violinista per passare XML per MVC ActionController ? Se cerco di impostare il valore del corpo come materie prime per l’xml non funziona..

E per i punti bonus come faccio a fare questo da VBscript/Classic ASP?

Attualmente ho

DataToSend = "name=JohnSmith"

          Dim xml
         Set xml = server.Createobject("MSXML2.ServerXMLHTTP")
   xml.Open "POST", _
             "http://localhost:1303/Home/Test", _
             False
 xml.setRequestHeader "Content-Type", "application/x-www-form-urlencoded"
 xml.send DataToSend
  • cosa si imposta l’intestazione Content-Type a quando si sta tentando di inviare XML nel corpo? Potrebbe essere utile se avete aggiornato il vostro domanda di mostrare tutto quello che il Compositore scheda che stai inviando.
  • trovato la risposta, avevo bisogno di un modo per infilare un pezzo di XML in coppia chiave/valore e utilizzando il ActionFilter sembra funzionare.. Ora ho solo bisogno di capire come effettuare il parsing di XML in ASP Classico..
InformationsquelleAutor punkouter | 2013-07-30

 

5 Replies
  1. 10

    Non è possibile il passaggio diretto di dati XML come file controller MVC. Uno dei migliori metodo è il passaggio di dati XML come Stream con un HTTP post.

    Per la Pubblicazione di XML,

    1. Di convertire i dati XML di un Torrente e collegato al Header HTTP
    2. Impostare il tipo di contenuto “text/xml; encoding=’utf-8′”

    Consultare questo post stackoverflow per ulteriori dettagli sulla pubblicazione XML per Controller MVC

    Per il recupero di XML nel controller, utilizzare il seguente metodo

    [HttpPost] 
    public ActionResult Index()
    {
        HttpWebResponse response = (HttpWebResponse)request.GetResponse();
    
        if (response.StatusCode == HttpStatusCode.OK)
        {
            //as XML: deserialize into your own object or parse as you wish
            var responseXml = XDocument.Load(response.GetResponseStream());
    
            //in responseXml variable you will get the XML data
        }
    }
  2. 2

    Per passare i dati come una puntura in MVC è necessario creare il proprio tipo di supporto formatter per gestire il testo normale. Quindi aggiungere il formatter per la sezione config.

    Per utilizzare il nuovo formattatore di specificare il Tipo di Contenuto per il formatter, come
    text/plain.

    Campione formattatore di testo

    using System;
    using System.Net.Http.Formatting;
    using System.Net.Http.Headers;
    using System.Threading.Tasks;
    using System.IO;
    using System.Text;
    
    namespace SampleMVC.MediaTypeFormatters
    {
        public class TextMediaTypeFormmatter : XmlMediaTypeFormatter
        {
            private const int ByteChunk = 1024;
            private UTF8Encoding StringEncoder = new UTF8Encoding();
    
            public TextMediaTypeFormmatter()
            {
                base.UseXmlSerializer = true;
                SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/plain"));
            }
    
            public override bool CanReadType(Type type)
            {
                if (type == typeof(string))
                {
                    return true;
                }
                return false;
            }
    
            public override bool CanWriteType(Type type)
            {
                if (type == typeof(string))
                {
                    return true;
                }
                return false;
            }
    
            public override Task<object> ReadFromStreamAsync(Type type, Stream readStream, System.Net.Http.HttpContent content, IFormatterLogger formatterLogger)
            {
                StringBuilder StringData = new StringBuilder();
                byte[] StringBuffer = new byte[ByteChunk];
                int BytesRead = 0;
    
                Task<int> BytesReadTask = readStream.ReadAsync(StringBuffer, 0, ByteChunk);
                BytesReadTask.Wait();
    
                BytesRead = BytesReadTask.Result;
                while (BytesRead != 0)
                {
                    StringData.Append(StringEncoder.GetString(StringBuffer, 0, BytesRead));
                    BytesReadTask = readStream.ReadAsync(StringBuffer, 0, ByteChunk);
                    BytesReadTask.Wait();
    
                    BytesRead = BytesReadTask.Result;
                }
    
                return Task<object>.Run(() => BuilderToString(StringData));
            }
    
            private object BuilderToString(StringBuilder StringData)
            {
                return StringData.ToString();
            }
    
            public override Task WriteToStreamAsync(Type type, object value, Stream writeStream, System.Net.Http.HttpContent content, System.Net.TransportContext transportContext)
            {
                byte[] StringBuffer = StringEncoder.GetBytes((string)value);
                return writeStream.WriteAsync(StringBuffer, 0, StringBuffer.Length);
            }
        }
    }

    Metodo Controller:

    [HttpPost]
    public async Task<HttpResponseMessage> UsingString([FromBody]string XmlAsString)
    {
        if (XmlAsString == null)
        {
            return this.Request.CreateResponse(HttpStatusCode.BadRequest);
        }
    
        return this.Request.CreateResponse(HttpStatusCode.OK, new { });
    }

    Installazione in WebApiConfig.cs il metodo di Registrazione:

    config.Formatters.Add(new TextMediaTypeFormmatter());

    Fiddler intestazioni:

    User-Agent: Fiddler
    Content-Type: text/plain
    • Questo è il metodo che ha funzionato per me.
  3. 0

    Controller MVC non è la scelta ideale per la gestione delle richieste, ma che era il compito, quindi cerchiamo di arrivare ad essa. Facciamo un XML che ho per accettare:

    <document>
    <id>123456</id>
        <content>This is document that I posted...</content>
        <author>Michał Białecki</author>
        <links>
            <link>2345</link>
            <link>5678</link>
        </links>
    </document>

    Ho provato un paio di soluzioni con built-in del parametro di deserializzazione, ma nessuno sembra funzionare e, infine, sono andato con la deserializzazione di una richiesta del corpo di un metodo. Ho creato un helper generico di classe per:

    public static class XmlHelper
    {
        public static T XmlDeserializeFromString<T>(string objectData)
        {
            var serializer = new XmlSerializer(typeof(T));
    
            using (var reader = new StringReader(objectData))
            {
                return (T)serializer.Deserialize(reader);
            }
        }
    }

    Ho decorato il mio DTO con gli attributi xml:

    [XmlRoot(ElementName = "document", Namespace = "")]
    public class DocumentDto
    {
        [XmlElement(DataType = "string", ElementName = "id")]
        public string Id { get; set; }
    
        [XmlElement(DataType = "string", ElementName = "content")]
        public string Content { get; set; }
    
        [XmlElement(DataType = "string", ElementName = "author")]
        public string Author { get; set; }
    
        [XmlElement(ElementName = "links")]
        public LinkDto Links { get; set; }
    }
    
    public class LinkDto
    {
        [XmlElement(ElementName = "link")]
        public string[] Link { get; set; }
    }

    E usato tutto in un controller di:

    public class DocumentsController : Controller
    {
        //documents/sendDocument
        [HttpPost]
        public ActionResult SendDocument()
        {
            try
            {
                var requestContent = GetRequestContentAsString();
                var document = XmlHelper.XmlDeserializeFromString<DocumentDto>(requestContent);
    
                return new HttpStatusCodeResult(HttpStatusCode.OK);
            }
            catch (System.Exception)
            {
                //logging
                return new HttpStatusCodeResult(HttpStatusCode.InternalServerError);
            }
        }
    
        private string GetRequestContentAsString()
        {
            using (var receiveStream = Request.InputStream)
            {
                using (var readStream = new StreamReader(receiveStream, Encoding.UTF8))
                {
                    return readStream.ReadToEnd();
                }
            }
        }
    }

    Per utilizzarlo, basta inviare una richiesta utilizzando, per esempio, Postino. Io sono l’invio di una richiesta POST per http://yourdomain.com/documents/sendDocument endpoint con xml corpo di cui sopra. Un dettaglio degno di nota è un colpo di testa. Aggiungere Content-Type: text/xml, o richiesta di lavoro.

    E funziona:
    Come POST XML in un Controller MVC? (invece di chiave/valore)

    Si può vedere l’intero post sul mio blog: http://www.michalbialecki.com/2018/04/25/accept-xml-request-in-asp-net-mvc-controller/

  4. -1

    Per inviare la richiesta tramite VBScript ho usato l’oggetto di WinHttp cioè “WinHttp.WinHttpRequest.5.1”.

    Sotto è una funzione che ho scritto e questo invia richiesta XML che si passa e restituisce la risposta:

    ' -----------------------------------------
    ' Method: sendRequest()
    ' Descrip: send the web service request as SOAP msg
    ' -----------------------------------------
    Public Function sendRequest(p_SOAPRequest)
        Const METHOD_NAME = "sendRequest()"
        Dim objWinHttp
        Dim strResponse
        Dim URL
        URL = "http:someURL.com"
        Const WINHTTP_OPTION_SECURITY_FLAGS = 13056 '13056: Ignores all SSL Related errors 
        Const WinHttpRequestOption_SslErrorIgnoreFlags = 4 'http://msdn.microsoft.com/en-us/library/Aa384108
    
        Set objWinHttp = CreateObject("WinHttp.WinHttpRequest.5.1")
    
        'Open HTTP connection
        Call objWinHttp.Open("POST", URL, False)
    
        'Set request headers
        Call objWinHttp.setRequestHeader("Content-Type", m_CONTENT_TYPE)
        Call objWinHttp.setRequestHeader("SOAPAction", URL)
    
        'Ignore the requirement for a security certificate:
        'http://msdn.microsoft.com/en-us/library/windows/desktop/aa384086(v=vs.85).aspx
        objWinHttp.Option(WinHttpRequestOption_SslErrorIgnoreFlags) = WINHTTP_OPTION_SECURITY_FLAGS
    
        'Send SOAP request
        On Error Resume Next
        objWinHttp.Send p_SOAPRequest
    
        If Err Then
            m_objLogger.error(METHOD_NAME & " error " & Err.Number & ": " & Err.Description)
            Err.Clear
        End If
    
        'disable error handling
        On Error GoTo 0
    
        'Get XML Response
        strResponse = objWinHttp.ResponseText
    
        'cleanup
        Set objWinHttp = Nothing
    
        sendRequest = strResponse
    End Function
    • Ho guardato in che WinHttp.WinHttpRequest.5.1, ma non era sicuro di come installarlo.. ho già MSXML2.ServerXMLHTTP di lavoro .. il suo solo che ho bisogno di trovare un modo per passare un intera stringa XML per il POST di azione e limitato coppia chiave/valore

Lascia un commento