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

我试图将数据发布到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,byteArray.Length);
        }

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

当我将请求的contenttype设置为“application / x-www-form-urlencoded”GetReponse()失败,服务器错误代码为500.当我评论出来并且只对httpscode的xml数据“interchangeXml”进行评论时,发送帖子但只有第3个参数“label”到达控制器.其他人都是空的.

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

谢谢!

更新

我通过查询字符串发送除XML之外的所有参数.但是,现在的问题是我不知道如何访问控制器操作中的发布数据.有人能告诉我如何使用我的Controller Action从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应用程序,它显然会使用视图模型:

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实例.现在这是严肃的事情.

相关文章

1 在Visual Studio 中创建一个Asp.NET WebApi 项目,项目名:...
using ImpromptuInterface; using System; using System.Dyn...
https://blog.csdn.net/michaelgong/article/details/431485...
C#11添加了文件作用域类型功能:一个新的file修饰符,可以应...
在.NET中Newtonsoft.Json(Json.NET)是我们常用来进行Json序列...
设置允许跨域访问的网址--> 设置预检有效时间--&...