我如何使用HttpWebRequest的POST数据到MVC控制器? [英] How do I post data to MVC Controller using HttpWebRequest?

查看:83
本文介绍了我如何使用HttpWebRequest的POST数据到MVC控制器?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想数据发布到MVC控制器的行动,但没有成功为止。

下面是后数据的结构:

 私人字符串makeHttpPostString(XmlDocument的interchangeFile)
    {
        字符串postDataString =UID = {0}&安培;本土化= {1}&安培;标签= {2}&安培; interchangeDocument = {3};        InterchangeDocument interchangeDocument =新InterchangeDocument(interchangeFile);
        使用(VAR的StringWriter =新的StringWriter())
        使用(VAR的XmlTextWriter = XmlWriter.Create(StringWriter的))
        {
            interchangeFile.WriteTo(XmlTextWriter的);
            字符串interchangeXml = HttpUtility.UrlEn code(stringWriter.GetStringBuilder()的ToString());
            字符串HWID = interchangeDocument.DocumentKey.Hwid;
            字符串本地化= interchangeDocument.DocumentKey.Localization.ToString();
            字符串标签= ConfigurationManager.AppSettings [previewLabel];            回报(的String.Format(postDataString,HWID,本地化,标签,interchangeXml));
        }    }

下面是请求:

 的HttpWebRequest的WebRequest =(HttpWebRequest的)WebRequest.Create(controllerUrl);        webRequest.Method =POST;
      // webRequest.ContentType =应用/的X WWW的形式urlen codeD;        字符串POSTDATA = makeHttpPostString(interchangeFile);
        字节[]的字节数组= Encoding.UTF8.GetBytes(POSTDATA);
        webRequest.ContentLength = byteArray.Length;        使用(流数据流= webRequest.GetRequestStream())
        {
            dataStream.Write(字节数组,0,byteArray.Length);
        }        HttpWebResponse WebResponse类=(HttpWebResponse)webRequest.GetResponse();

当我设置的请求的contentType为应用程序/ x-WWW的形式urlen codeDGetReponse()失败,服务器错误code 500当我评论说出来,只有httpen code xml数据,interchangeXml的帖子发出,但只有第三个参数,标签到达控制器。其余均为空。

什么是张贴值控制器动作时,这些价值观之一是XML数据的正确方法是什么?

谢谢!

更新

我把所有的参数通过查询字符串的XML的除外。然而,现在的问题是,我不知道如何来访问控制器动作已发布数据。谁能告诉我怎么从我的控制器操作访问来自Htt的prequest的XM​​L?

更新

我已经重构了超过code。通过达林使用的建议作出了我。我使用WebClient的UploadValues​​()recieveing​​内部服务器错误(500)。

动作:

 的[AcceptVerbs(HttpVerbs.Post)
        公众的ActionResult构建preVIEW(previewViewModel模型)
        {
            ...
        }

请求:

 私人字符串PostToSxController(XmlDocument的interchangeFile,串controllerUrl)
        {
            VAR xmlInterchange =新InterchangeDocument(interchangeFile);
            使用(VAR的客户=新的WebClient())
            {
                VAR值=新的NameValueCollection()
                                 {
                                     {UID,xmlInterchange.DocumentKey.Hwid},
                                     {本土化,xmlInterchange.DocumentKey.Localization.ToString()},
                                     {标签,ConfigurationManager.AppSettings [previewLabel]},
                                     {interchangeDocument,interchangeFile.OuterXml}
                                 };                 字节[]的结果= NULL;                尝试
                {
                    结果= client.UploadValues​​(controllerUrl,价值观);
                }
                赶上(引发WebException前)
                {
                    VAR errorResponse = ex.Response;
                    VAR的errorMessage = ex.Message;
                }                编码编码= Encoding.UTF8;
               返回encoding.GetString(结果);
            }
        }

路线:

  routes.MapRoute(
                建立preVIEW
                SymptomTopics /编译preVIEW / {}模式,
                新{控制器=SymptomTopics,行动=建立preVIEW模型= UrlParameter.Optional}
            );


解决方案

太复杂,不安全的客户端code与所有这些请求和响应。您没有任何编码的请求参数的,更何况这个XML这可能是要去,如果你不带code得当打破一切。

为此,我将简化并离开管道code约编码等...到.NET框架:

 使用(VAR的客户=新的WebClient())
{
    VAR值=新的NameValueCollection
    {
        {UID,HWID},
        {本土化,本地化},
        {标签,标签},
        {interchangeDocument,interchangeFile.OuterXml},
    };
    VAR的结果= client.UploadValues​​(controllerUrl,价值观);
    // TODO:做控制器操作返回的结果的东西
}

至于服务器端来讲,因为每个正确设计ASP.NET MVC应用程序,它显然会使用一个视图模型:

 公共类MyViewModel
{
    公共字符串的Uid {搞定;组; }
    公共字符串本地化{搞定;组; }
    公共字符串标签{搞定;组; }
    公共字符串InterchangeDocument {搞定;组; }
}

  [HttpPost]
公众的ActionResult美孚(MyViewModel模型)
{
    // TODO:做这里的东西值
    ...
}

显然,这还可以进一步通过写反射XML文档的结构的图模型截取的步骤:

 公共类Foo
{
    公共字符串酒吧{搞定;组; }
    公共字符串巴兹{搞定;组; }
}

然后您的视图模式将成为:

 公共类MyViewModel
{
    公共字符串的Uid {搞定;组; }
    公共字符串本地化{搞定;组; }
    公共字符串标签{搞定;组; }
    公共富InterchangeDocument {搞定;组; }
}

和最后一部分是写在键入将使用XML序列化(或其他)反序列化回<$ C $自定义模型绑定C> InterchangeDocument HTTP POST的值转换成实例。现在,这是严重的企业。

I am trying to post data to MVC controller action but have been unsuccessful so far.

Here is the structure of the post data:

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

    }

Here is the request:

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

When I set the contenttype of the request to "application/x-www-form-urlencoded" GetReponse() fails with server error code 500. When I comment that out and only httpencode the xml data, "interchangeXml", the post is sent but only the 3rd parameter, "label" reaches the controller. The others are null.

What is the correct way to post values to a controller action when one of those values is xml data?

Thanks!

Update

I am send all the parameter with the exception of the XML via the query string. However, the problem now is that I do not know how to access the posted data in the controller action. Can someone tell me how I access the xml from the HttpRequest from with my Controller Action?

Update

I have refactored the above code to use the suggests made to me by Darin. I am recieveing an internal server error (500) using the WebClient UploadValues().

Action:

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

Request:

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


            }
        }

Route:

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

解决方案

Too complicated and unsafe your client code with all those requests and responses. You are not encoding any of your request parameters, not to mention this XML which is probably gonna break everything if you don't encode it properly.

For this reason I would simplify and leave the plumbing code about encoding, etc... to the .NET framework:

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
}

As far as the server side is concerned, as every properly architected ASP.NET MVC application, it would obviously use a view model:

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

with:

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

Obviously this could be taken a step further by writing a view model reflecting the structure of your XML document:

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

and then your view model will become:

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

and the last part would be to write a custom model binder for the Foo type that will use a XML serializer (or whatever) to deserialize back the InterchangeDocument POSTed value into a Foo instance. Now that's serious business.

这篇关于我如何使用HttpWebRequest的POST数据到MVC控制器?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆