19

使用 Fiddler 我可以通过身体

someXml=ThisShouldBeXml

然后在控制器中

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

将此数据作为字符串获取

如何让提琴手将 XML 传递给 MVC ActionController ?如果我尝试将正文中的值设置为原始 xml,它将不起作用..

对于奖励积分,我如何从 VBscript/Classic ASP 执行此操作?

我目前有

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
4

5 回答 5

12

您不能直接将 XML 数据作为文件传递给 MVC 控制器。最好的方法之一是使用 HTTP post 将 XML 数据作为 Stream 传递。

对于发布 XML,

  1. 将 XML 数据转换为 Stream 并附加到 HTTP Header
  2. 将内容类型设置为“text/xml; encoding='utf-8'”

有关将 XML 发布到 MVC 控制器的更多详细信息,请参阅此 stackoverflow 帖子

要在控制器中检索 XML,请使用以下方法

[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
    }
}
于 2015-04-28T08:26:15.477 回答
3

这似乎是向 MVC 控制器支付 XML 的方式

如何将 XML 作为 POST 传递给 ASP MVC .NET 中的 ActionResult

我试图让它与 WEB API 一起工作,但不能,所以我不得不使用 MVC 'Controller' 来代替。

于 2013-07-30T21:17:55.880 回答
2

为了在 MVC 中将数据作为字符串传递,您必须创建自己的媒体类型格式化程序来处理纯文本。然后将格式化程序添加到配置部分。

要使用新的格式化程序,请为该格式化程序指定 Content-Type,例如 text/plain

文本的示例格式化程序

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);
        }
    }
}

控制器方法:

[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 { });
}

WebApiConfig.cs 注册方法中的设置:

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

提琴手头:

User-Agent: Fiddler
Content-Type: text/plain
于 2015-04-30T15:56:45.390 回答
1

MVC 控制器对于此类请求处理并不理想,但这就是任务,所以让我们开始吧。让我们有一个我接受的 XML:

<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>

我尝试了一些带有内置参数反序列化的解决方案,但似乎都不起作用,最后,我在方法体中反序列化了一个请求。我为它创建了一个辅助泛型类:

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);
        }
    }
}

我用 xml 属性装饰了我的 DTO:

[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; }
}

并在控制器中使用了所有这些:

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();
            }
        }
    }
}

要使用它,只需使用例如 Postman 发送请求。我正在使用上面提到的 xml 正文向http://yourdomain.com/documents/sendDocument端点发送 POST 请求。一个值得一提的细节是标题。添加 Content-Type: text/xml,或请求工作。

它有效: 工作反序列化

你可以在我的博客上看到整篇文章:http: //www.michalbialecki.com/2018/04/25/accept-xml-request-in-asp-net-mvc-controller/

于 2018-04-26T13:59:32.293 回答
-1

为了使用 VBScript 发送请求,我使用了 WinHttp 对象,即“WinHttp.WinHttpRequest.5.1”。

下面是我编写的一个函数,它发送您传入的 XML 请求并返回响应:

' -----------------------------------------
' 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
于 2013-07-30T15:56:28.753 回答