繁体   English   中英

如何使用 HttpWebRequest 将数据发布到 MVC Controller?

[英]How do I post data to MVC Controller using HttpWebRequest?

我正在尝试将数据发布到 MVC controller 操作,但到目前为止还没有成功。

这是帖子数据的结构:

private string makeHttpPostString(XmlDocument interchangeFile)
    {
        string postDataString = "uid={0}&localization={1}&label={2}&interchangeDocument={3}";

        InterchangeDocument interchangeDocument =  new InterchangeDocument(interchangeFile);
        using (var stringWriter = new StringWriter())
        using (var xmlTextWriter = XmlWriter.Create(stringWriter))
        {
            interchangeFile.WriteTo(xmlTextWriter);
            string interchangeXml = HttpUtility.UrlEncode(stringWriter.GetStringBuilder().ToString());
            string hwid = interchangeDocument.DocumentKey.Hwid;
            string localization = interchangeDocument.DocumentKey.Localization.ToString();
            string label = ConfigurationManager.AppSettings["PreviewLabel"];

            return (string.Format(postDataString, hwid, localization, label, interchangeXml));
        }

    }

这是请求:

 HttpWebRequest webRequest = (HttpWebRequest) WebRequest.Create(controllerUrl);

        webRequest.Method = "POST";
      //  webRequest.ContentType = "application/x-www-form-urlencoded";

        string postData = makeHttpPostString(interchangeFile);
        byte[] byteArray = Encoding.UTF8.GetBytes(postData);
        webRequest.ContentLength = byteArray.Length;

        using (Stream dataStream = webRequest.GetRequestStream())
        {
            dataStream.Write(byteArray, 0, byteArray.Length);
        }

        HttpWebResponse webresponse = (HttpWebResponse) webRequest.GetResponse();

当我将请求的内容类型设置为“application/x-www-form-urlencoded”时,GetReponse() 失败,服务器错误代码为 500。当我将其注释掉并且仅对 xml 数据“interchangeXml”进行 httpencode 时,将发送帖子但只有第三个参数“标签”到达 controller。 其他的是 null。

当这些值之一是 xml 数据时,将值发布到 controller 操作的正确方法是什么?

谢谢!

更新

我通过查询字符串发送除 XML 之外的所有参数。 但是,现在的问题是我不知道如何访问 controller 操作中发布的数据。 有人可以告诉我如何使用 Controller 操作从 HttpRequest 访问 xml 吗?

更新

我已经重构了上面的代码以使用 Darin 给我的建议。 我使用 WebClient UploadValues() 收到内部服务器错误 (500)。

行动:

[AcceptVerbs(HttpVerbs.Post)]
        public ActionResult BuildPreview(PreviewViewModel model)
        {
            ...
        }

要求:

private string PostToSxController(XmlDocument interchangeFile, string controllerUrl)
        {
            var xmlInterchange = new InterchangeDocument(interchangeFile);
            using (var client = new WebClient())
            {
                var values = new NameValueCollection()
                                 {
                                     {"uid", xmlInterchange.DocumentKey.Hwid},
                                     {"localization", xmlInterchange.DocumentKey.Localization.ToString()},
                                     {"label", ConfigurationManager.AppSettings["PreviewLabel"]},
                                     {"interchangeDocument", interchangeFile.OuterXml }
                                 };

                 byte[] result = null;

                try
                {
                    result = client.UploadValues(controllerUrl, values);
                }
                catch(WebException ex)
                {
                    var errorResponse = ex.Response;
                    var errorMessage = ex.Message;
                }

                Encoding encoding = Encoding.UTF8;
               return encoding.GetString(result);


            }
        }

路线:

routes.MapRoute(
                "BuildPreview",
                "SymptomTopics/BuildPreview/{model}",
                new { controller = "SymptomTopics", action = "BuildPreview", model = UrlParameter.Optional  }
            );

对于所有这些请求和响应,您的客户端代码过于复杂和不安全。 您没有对任何请求参数进行编码,更不用说这个 XML 如果您没有正确编码它可能会破坏一切。

出于这个原因,我将简化有关编码等的管道代码并将其留给 .NET 框架:

using (var client = new WebClient())
{
    var values = new NameValueCollection
    {
        { "uid", hwid },
        { "localization", localization },
        { "label", label },
        { "interchangeDocument", interchangeFile.OuterXml },
    };
    var result = client.UploadValues(controllerUrl, values);
    // TODO: do something with the results returned by the controller action
}

就服务器端而言,作为每个正确架构的 ASP.NET MVC 应用程序,它显然会使用视图 model:

public class MyViewModel
{
    public string Uid { get; set; }
    public string Localization { get; set; }
    public string Label { get; set; }
    public string InterchangeDocument { get; set; }
}

和:

[HttpPost]
public ActionResult Foo(MyViewModel model)
{
    // TODO: do something with the values here
    ...
}

显然,这可以通过编写反映 XML 文档结构的视图 model 来更进一步:

public class Foo
{
    public string Bar { get; set; }
    public string Baz { get; set; }
}

然后您的视图 model 将变为:

public class MyViewModel
{
    public string Uid { get; set; }
    public string Localization { get; set; }
    public string Label { get; set; }
    public Foo InterchangeDocument { get; set; }
}

最后一部分是为Foo类型编写自定义 model 绑定程序,该绑定程序将使用 XML 序列化程序(或其他)将InterchangeDocument POSTed 值反序列化回Foo实例。 现在这是严肃的事情。

我在这里与同一头野兽搏斗: 尝试将 controller 操作设置为 Xml 端点

您可能会收到内部服务器错误,因为您有页面验证(解决方案:使用 ValidateInput(false) 添加),或者您没有在请求中发送 Accept-Encoding header。 我非常想听听如何让 MVC 在没有接受编码 HTTP header 的情况下接受发布的输入...

I just found that you can call a controller, even a dependency injected one, even from a Web Forms code behind using the "T4MVC" Nuget package:

https://github.com/T4MVC/T4MVC

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM