如何使用 HttpWebRequest 将数据发布到 MVC 控制器

本文关键字:MVC 控制器 数据 何使用 HttpWebRequest | 更新日期: 2023-09-27 17:58:40

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

以下是帖子数据的结构:

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 数据进行 httpencoding "interchangeXml"时,帖子被发送,但只有第三个参数"标签"到达控制器。其他为空。

当其中一个值是 xml 数据时,将值发布到控制器操作的正确方法是什么?

谢谢!

更新

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

更新

我已经重构了上面的代码,以使用Darin向我提出的建议。我收到一个内部服务器错误 (500( 使用 WebClient 上传值 ((。

行动:

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

如何使用 HttpWebRequest 将数据发布到 MVC 控制器

太复杂和不安全的客户端代码与所有这些请求和响应。您没有对任何请求参数进行编码,更不用说这个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 应用程序一样,它显然会使用视图模型:

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 文档结构的视图模型来更进一步:

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

然后您的视图模型将变为:

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

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

我在这里与同一只野兽搏斗: 尝试将控制器操作设置为 Xml 端点

您可能会收到内部服务器错误,因为您打开了页面验证(解决方案:使用 ValidateInput(false(( 进行附加(,或者您没有随请求一起发送接受编码标头。我非常想听听如何让 MVC 在没有接受编码 HTTP 标头的情况下接受发布的输入......

我刚刚发现你可以调用一个控制器,甚至是依赖注入的控制器,甚至可以使用"T4MVC"Nuget包从后面的Web Forms代码调用:

https://github.com/T4MVC/T4MVC