2011-06-07 10 views
6

Estoy tratando de publicar datos en la acción del controlador MVC, pero hasta ahora no han tenido éxito.¿Cómo publico datos en MVC Controller usando HttpWebRequest?

Aquí es la estructura de los datos de mensaje:

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

    } 

Aquí está la solicitud:

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

Cuando fijo el contenttype de la solicitud a "application/x-www-form- urlencoded "GetReponse() falla con el código de error 500 del servidor. Cuando lo comente y solo httpencode los datos xml," interchangeXml ", la publicación se envía pero solo el 3er parámetro," label "llega al controlador. Los otros son nulos.

¿Cuál es la forma correcta de publicar valores en una acción del controlador cuando uno de esos valores es xml data?

Gracias!

actualización

Soy enviar todos los parámetros con la excepción del XML a través de la cadena de consulta. Sin embargo, el problema ahora es que no sé cómo acceder a los datos publicados en la acción del controlador. ¿Puede alguien decirme cómo accedo al xml desde la HttpRequest desde mi Acción del controlador?

actualización

que han rediseñado el código anterior para utilizar el sugiere que me hizo Darin. Estoy recibiendo un error interno del servidor (500) usando WebClient UploadValues ​​().

Acción:

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

Solicitud:

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


      } 
     } 

Ruta:

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

¿Cuál es la estructura de datos de acciones de su MVC espera? ¿No podría simplemente publicar todos los datos en xml, a diferencia de la cadena de consulta? – Jay

+0

La acción del controlador espera 4 cadenas: intercambioXml, hwid, localización y etiqueta. No ... el xml no contiene y no contendrá los otros valores que intento publicar. – Nick

+0

¿Ha intentado utilizar una herramienta como Fiddler o Firebug para ver exactamente lo que su cliente está enviando al servidor? Puede que no esté saliendo correctamente. – Tridus

Respuesta

12

demasiado complicado y peligroso código de su cliente con todas esas solicitudes y respuestas. No está codificando ninguno de los parámetros de su solicitud, por no mencionar este XML que probablemente romperá todo si no lo codifica correctamente.

Por esta razón me gustaría simplificar y dejar el código de plomería sobre la codificación, etc ... con el marco .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 
} 

En lo que se refiere a la parte del servidor, ya que cada ASP adecuadamente con arquitectura.aplicación MVC NET, sería obviamente utilizar una vista de modelo:

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

con:

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

Obviamente, esto podría ser un paso más al escribir un modelo de vista que refleja la estructura del documento XML:

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

y entonces su modelo de vista se convertirá en:

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

y la última parte sería escribir un archivador de modelo personalizado para el tipo Foo que usará un serializador XML (o lo que sea) para deserializar el valor InterchangeDocument POSTed en una instancia Foo. Ahora eso es un asunto serio.

+0

Gracias por la solución directa. Voy a intentar usar el objeto WebClient para simplificar las cosas. Dijiste que no estaba codificando el xml .. string interchangeXml = HttpUtility.UrlEncode (stringWriter.GetStringBuilder(). ToString()); ¿No es esta la forma correcta de codificar xml? – Nick

+1

WebClient acaba de recibir 500 sin tocar la acción. ¿Cómo debería verse la ruta ahora que la acción está esperando un viewModel? Creé un viewModel como el que sugirió. – Nick

+0

@Nick, ¿cuál es el mensaje de este error 500? –

1

estoy sopesando la misma bestia aquí: Trying to set up a controller action as Xml endpoint

Usted podría estar recibiendo el error interno del servidor, ya sea porque tiene la validación de la página (solución: addotate con ValidateInput (falso)), o no lo eres enviando un encabezado Aceptar-Codificar con su solicitud. Me gustaría mucho escuchar cómo puedo hacer que MVC acepte entradas publicadas sin el encabezado HTTP Aceptar codificación ...

0

Acabo de encontrar que puede llamar a un controlador, incluso uno de dependencia inyectado, incluso desde una Web código formas detrás de usar el paquete "T4MVC" Nuget:

https://github.com/T4MVC/T4MVC

Cuestiones relacionadas