Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/336.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何使用HttpWebRequest将数据发布到MVC控制器?_C#_Asp.net Mvc - Fatal编程技术网

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

C# 如何使用HttpWebRequest将数据发布到MVC控制器?,c#,asp.net-mvc,C#,Asp.net Mvc,我正在尝试将数据发布到MVC控制器操作,但迄今为止未成功 以下是post数据的结构: private string makeHttpPostString(XmlDocument interchangeFile) { string postDataString = "uid={0}&localization={1}&label={2}&interchangeDocument={3}"; InterchangeDocument int

我正在尝试将数据发布到MVC控制器操作,但迄今为止未成功

以下是post数据的结构:

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();
当我将请求的contenttype设置为“application/x-www-form-urlencoded”时,GetReponse()失败,服务器错误代码为500。当我注释out并且仅httpencode对xml数据“interchangeXml”进行编码时,post被发送,但只有第三个参数“label”到达控制器。其他的都是空的

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

谢谢

更新

我将通过查询字符串发送除XML之外的所有参数。但是,现在的问题是,我不知道如何访问控制器操作中发布的数据。有人能告诉我如何使用控制器操作从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 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
}
就服务器端而言,对于每一个架构正确的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; }
}
与:

显然,通过编写一个反映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序列化程序(或任何东西)将
interchangeddocument
发布的值反序列化回
Foo
实例。现在这是一件严肃的事情。

我在这里和同一头野兽搏斗:


您可能会收到内部服务器错误,因为您在上进行了页面验证(解决方案:addotate with ValidateInput(false)),或者您没有在请求中发送接受编码头。我非常想知道如何让MVC在不使用accept Encoding HTTP头的情况下接受发布的输入…

我刚刚发现,您可以调用控制器,甚至是依赖项注入的控制器,甚至可以使用“T4MVC”Nuget包从Web表单代码中调用:


您的MVC操作需要什么样的数据结构?您是否可以将所有数据以xml而不是查询字符串的形式发布?控制器操作需要4个字符串:interchangeXml、hwid、localization和label。不xml不包含也不会包含我试图发布的其他值。您是否尝试过使用Fiddler或Firebug之类的工具来查看您的客户端发送到服务器的确切内容?它可能输出不正确。我正在使用c#从一个thik客户端进行httprequest。请求不是来自浏览器,因此我认为firebug或fiddler不适用。我认为@Tridus的意思是通过网站的web界面访问网站,并对请求进行修改,以查看是否可以匹配它。即使您有四个不同的值,其中一个是xml,您也可以使用xml编写整个文章,或者json和MVC应该足够聪明,可以将对象放在一起。我知道至少MVC 3可以做到这一点。谢谢你提供的完整解决方案。我将尝试使用WebClient对象来简化事情。你说我没有对xml进行编码。。字符串交换xml=HttpUtility.UrlEncode(stringWriter.GetStringBuilder().ToString());这不是编码xml的正确方法吗?WebClient只收到一个500而没有点击操作。既然操作需要viewModel,那么路线应该是什么样子的呢。我创建了一个与您建议的视图模型一样的视图模型。@Darin我的catch块中的状态报告“协议错误”。“远程服务器返回错误:(500)内部服务器错误”@Nick,查看内部异常。它应该是一个HttpException,您可以从中提取服务器的确切响应消息。或者让服务器应用程序记录错误,以便进一步缩小问题范围。很抱歉,从您提供的信息(应用程序抛出500个状态代码)来看,我无法为您提供太多帮助。@Darin不幸的是,没有内部异常,该异常不能为我提供任何不那么模糊的信息。
public class MyViewModel
{
    public string Uid { get; set; }
    public string Localization { get; set; }
    public string Label { get; set; }
    public Foo InterchangeDocument { get; set; }
}