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

Fre*_*ddy 10 xml asp.net-mvc json json.net actionresult

我试图为我的ASP MVC项目提供一个简单的RESTful API.我将无法控制此API的客户端,它们将通过POST方法传递XML,该方法将包含在服务器端执行某些操作所需的信息,并提供带有操作结果的XML.发回XML时没有问题,问题是通过POST接收XML.我已经看到了一些JSON示例,但由于我不会控制我的客户端(从我的角度来看它甚至可能是一个telnet)我不认为JSON会起作用.我对么?

我见过一些例子,客户只是构造正确的表单格式作为请求主体的一部分,然后ASP解析消息,数据可用作FormCollection(?param1 = value1¶m2 = value2&等).但是,我想将纯XML作为消息体的一部分传递.

谢谢你的帮助,

bow*_*erm 10

@Freddy - 喜欢你的方法并使用以下代码改进它以简化流阅读:

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        HttpContextBase httpContext = filterContext.HttpContext;
        if (!httpContext.IsPostNotification)
        {
            throw new InvalidOperationException("Only POST messages allowed on this resource");
        }

        Stream httpBodyStream = httpContext.Request.InputStream;
        if (httpBodyStream.Length > int.MaxValue)
        {
            throw new ArgumentException("HTTP InputStream too large.");
        }

        StreamReader reader = new StreamReader(httpBodyStream, Encoding.UTF8);
        string xmlBody = reader.ReadToEnd();
        reader.Close();

        filterContext.ActionParameters["message"] = xmlBody;

        // Sends XML Data To Model so it could be available on the ActionResult
        base.OnActionExecuting(filterContext);
    }
Run Code Online (Sandbox Code Playgroud)

然后在Controller中,您可以以字符串形式访问xml:

[RestAPIAttribute]    
public ActionResult MyActionResult(string message)    
{         

}
Run Code Online (Sandbox Code Playgroud)


Fre*_*ddy 7

这可以通过使用ActionFilterAttribute来完成.操作过滤器基本上与操作结果之前或之后的请求相交.所以我刚为POST Action Result构建了一个自定义动作过滤器属性.这是我做的:

public class RestAPIAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        HttpContextBase httpContext = filterContext.HttpContext;
        if (!httpContext.IsPostNotification)
        {
            throw new InvalidOperationException("Only POST messages allowed on this resource");
        }
        Stream httpBodyStream = httpContext.Request.InputStream;

        if (httpBodyStream.Length > int.MaxValue)
        {
            throw new ArgumentException("HTTP InputStream too large.");
        }

        int streamLength = Convert.ToInt32(httpBodyStream.Length);
        byte[] byteArray = new byte[streamLength];
        const int startAt = 0;

        /*
         * Copies the stream into a byte array
         */
        httpBodyStream.Read(byteArray, startAt, streamLength);

        /*
         * Convert the byte array into a string
         */
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < streamLength; i++)
        {
            sb.Append(Convert.ToChar(byteArray[i]));
        }

        string xmlBody = sb.ToString();

        //Sends XML Data To Model so it could be available on the ActionResult

        base.OnActionExecuting(filterContext);
    }
}
Run Code Online (Sandbox Code Playgroud)

然后在你的控制器上的动作结果方法你应该做这样的事情:

    [RestAPIAttribute]
    public ActionResult MyActionResult()
    {
        //Gets XML Data From Model and do whatever you want to do with it
    }
Run Code Online (Sandbox Code Playgroud)

希望这有助于其他人,如果你认为有更优雅的方法,请告诉我.