I am trying to post some data to a ASP.NET MVC Controller Action. Current I am trying to use WebClient.UploadData() to post several parameters to my action.
The following will hit the action but all the parameters are null. How can get the posted data from the http request?
string postFormat = "hwid={0}&label={1}&interchange={2}localization={3}";
var hwid = interchangeDocument.DocumentKey.Hwid;
var interchange = HttpUtility.UrlEncode(sw.ToString());
var label = ConfigurationManager.AppSettings["PreviewLabel"];
var localization = interchangeDocument.DocumentKey.Localization.ToString();
string postData = string.Format(postFormat, hwid, interchange, label, localization);
using(WebClient client = new WebClient())
{
client.Encoding = Encoding.UTF8;
client.Credentials = CredentialCache.DefaultNetworkCredentials;
byte[] postArray = Encoding.ASCII.GetBytes(postData);
client.Headers.Add("Content-Type", "pplication/x-www-form-urlencoded");
byte[] reponseArray = client.UploadData("http://localhost:6355/SymptomTopics/BuildPreview",postArray);
var result = Encoding.ASCII.GetString(reponseArray);
return result;
}
Here is the Action I am calling
public ActionResult
BuildPreview(string hwid, string
label, string interchange, string
localization) {
... }
When this Action is reached all the parameters are null.
I have tried using the WebClient.UploadValue() and passing the data as a NameValueCollection. This method always returns a status of 500 and because I am making this http request from within the MVC application I cannot find a way to bebug this.
Any help getting this resolved would be super helpful.
-Nick
I corrected the Header to read:
client.Headers.Add("Content-Type", "application/x-www-form-urlencoded");
Now UploadData just errors immediately with with server error 500.
Just for laughs have a look in Request.Form and the RouteData in your controller to see if something ended up there.
I was able to get the post xml data from the Request objects InputStream property.
public ActionResult BuildPreview(string hwid, string label, string localization)
{
StreamReader streamReader = new StreamReader(Request.InputStream);
XmlDocument xmlDocument = new XmlDocument();
xmlDocument.LoadXml(streamReader.ReadToEnd());
...
}
As a stop-gap measure, you can always change your controller action to accept a FormCollection parameter and then reach in and access the form parameters by name directly.
To get the raw posted bytes from WebClient.UploadData("http://somewhere/BuildPreview", bytes)
public ActionResult BuildPreview()
{
byte[] b;
using (MemoryStream ms = new MemoryStream())
{
Request.InputStream.CopyTo(ms);
b = ms.ToArray();
}
...
}
Related
I have a rest endpoint that accepts a single custom object parameter containing two properties.
Let's call the param InfoParam
public class InfoParam
{
public long LongVar { get; set; }
public string StringVar { get; set; }
}
My code I have is as follows:
infoParam.LongVar = 12345678;
infoParam.StringVar = "abc"
var myRequest = (HttpWebRequest)WebRequest.Create(url);
myRequest.Method = "POST";
var content = string.Empty;
using (var theResponse = (HttpWebResponse)MyRequest.GetResponse())
{
using (var stream = theResponse.GetResponseStream())
{
using (var sr = new StreamReader(stream))
{
content = sr.ReadToEnd();
}
}
}
So I have the InfoParam variable, with the two values, but I can't figure out where to pass it in to the REST endpoint.
You need to turn the object into a stream of bytes that can be added to the Request stream - which will in turn be sent as the HTTP POST body. The format of these bytes needs to match what the server expects. REST endpoints usually expect these bytes to resemble JSON.
// assuming you have added Newtonsoft.JSON package and added the correct using statements
using (StreamWriter writer = new StreamWriter(myRequest.GetRequestStream()) {
string json = JsonConvert.SerializeObject(infoParam);
writer.WriteLine(json);
writer.Flush();
}
You'll probably want to set various other request parameters, like the Content-Type header.
You have to write it int the `Content (and set content-type). Check out How to: Send data by using the WebRequest class
The recommendation is to use System.Net.Http.HttpClient instead.
Please note that you should know what content the server expects ('application/x-www-form-urlencoded`, json, etc.)
The following snippet is from POST JSON data over HTTP
// Construct the HttpClient and Uri. This endpoint is for test purposes only.
HttpClient httpClient = new HttpClient();
Uri uri = new Uri("https://www.contoso.com/post");
// Construct the JSON to post.
HttpStringContent content = new HttpStringContent(
"{ \"firstName\": \"Eliot\" }",
UnicodeEncoding.Utf8,
"application/json");
// Post the JSON and wait for a response.
HttpResponseMessage httpResponseMessage = await httpClient.PostAsync(
uri,
content);
// Make sure the post succeeded, and write out the response.
httpResponseMessage.EnsureSuccessStatusCode();
var httpResponseBody = await httpResponseMessage.Content.ReadAsStringAsync();
Debug.WriteLine(httpResponseBody);
In your case the content would be something like this
HttpStringContent content = new HttpStringContent(
JsonConvert.SerializeObject(infoParam), // using Json.Net;
UnicodeEncoding.Utf8,
"application/json");
I want to send via POST request two parameters to a Web API service. I am currently receiving 404 not found when I try in the following way, as from msdn:
public static void PostString (string address)
{
string data = "param1 = 5 param2 = " + json;
string method = "POST";
WebClient client = new WebClient ();
string reply = client.UploadString (address, method, data);
Console.WriteLine (reply);
}
where json is a json representation of an object. This did not worked, I have tried with query parameters as in this post but the same 404 not found was returned.
Can somebody provide me an example of WebClient which sends two parameters to a POST request?
Note: I am trying to avoid wrapping both parameters in the same class only to send to the service (as I found the suggestion here)
I would suggest sending your parameters as a NameValueCollection.
Your code would look something like this when sending the parameters with a NameValueCollection:
using(WebClient client = new WebClient())
{
NameValueCollection requestParameters = new NameValueCollection();
requestParameters.Add("param1", "5");
requestParameters.Add("param2", json);
byte[] response = client.UploadValues("your url here", requestParameters);
string responseBody = Encoding.UTF8.GetString(response);
}
Using UploadValues will make it easier for you, since the framework will construct the body of the request and you won't have to worry about concatenating parameters or escaping characters.
I have managed to send both a json object and a simple value parameter by sending the simple parameter in the address link and the json as body data:
public static void PostString (string address)
{
string method = "POST";
WebClient client = new WebClient ();
string reply = client.UploadString (address + param1, method, json);
Console.WriteLine (reply);
}
Where address needs to expect the value parameter.
I've set up a page to do an HTTP Post with a Json serialized generic list, to a different page in ASP.net. When it goes to the new page though, I can't seem to find the body of the HTTP Post.
This is the method for the post:
public static void SendHttpPost(string json)
{
var httpWebRequest = (HttpWebRequest)WebRequest.Create("http://localhost:57102/Post.aspx");
httpWebRequest.ContentType = "text/json";
httpWebRequest.Method = "POST";
using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
{
streamWriter.Write(json);
streamWriter.Flush();
streamWriter.Close();
var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
var result = streamReader.ReadToEnd();
}
}
}
Although this is the first time I've done this, I presumed you would be able to access the Json using Request.Form or similar, but Request.Form is empty. I've had a good look at the VS degugger and can't see it anywhere in the Request object, but the content length is 68000 bytes, so I'm sure it's in there somewhere!
Can anyone point me in the right direction please? Many thanks
You can retrieve the Request Body using Request.InputStream as shown here : gist.github.com/leggetter/769688 !
I am wondering if HttpWebRequest can be used to fill a MVC model? I am trying to build a MVC 4 application where I take data from a college course listing page and massage it in a few different ways in my View. The examples that I have been seeing around have all taken a response stream and returned a string or have not been formatted for MVC (using console.write). Also, as far as I understand, the data as its being returned isn't in a JSON or XML format. Here is my controller so far...
public ActionResult Index()
{
string postData = "semester=20143Fall+2013+++++++++++++++++++++++++++++++&courseid=&subject=IT++INFORMATION+TECHNOLOGY&college=&campus=1%2C2%2C3%2C4%2C5%2C6%2C7%2C9%2CA%2CB%2CC%2CI%2CL%2CM%2CN%2CP%2CQ%2CR%2CS%2CT%2CW%2CU%2CV%2CX%2CZ&courselevel=&coursenum=&startTime=0600&endTime=2359&days=ALL&All=All+Sections";
byte[] dataArray = Encoding.UTF8.GetBytes (postData);
HttpWebRequest myRequest = (HttpWebRequest)WebRequest.Create("http://www3.mnsu.edu/courses/selectform.asp");
myRequest.Method = "POST";
myRequest.ContentType = "application/x-www-form-urlencoded";
myRequest.ContentLength = dataArray.Length;
using (WebResponse response = myRequest.GetResponse())
{
using (var reader = new StreamReader(response.GetResponseStream()))
{
//insert into a model? Maybe?
}
}
return View();
}
If HttbWebRequest can't be used, is there a way that would work? Or am I completely heading in the wrong direction?
You can using HttpWebRequest and WebResponse to get stream from your college course's web site. Then use HtmlAgilityPack to parse scrap in the stream and insert your desired value into model
I have the following MVC method.
[System.Web.Mvc.HttpPost]
public ActionResult Listen(string status)
{
CFStatusMessage statusMessage = new CFStatusMessage();
if (!string.IsNullOrEmpty(status))
{
statusMessage = Newtonsoft.Json.JsonConvert.DeserializeObject<CFStatusMessage>(status);
}
return Content(Server.HtmlEncode(status));// View(statusMessage);
}
I am trying to call the above method from Other application .. (Console). I am using HttpWebRequest to make a call to the MVC Method. Using the below code its able to call the method but the Parameter is always coming as empty string.
string content = "{\"status\":\"success\",\"payload\":\"some information\"}";
string url = "http://myrl.com";
var httpWRequest = (HttpWebRequest) WebRequest.Create(url);
httpWRequest.Method = "POST";
httpWRequest.ContentType = "text/json";
var encoding = new ASCIIEncoding();
byte[] data = encoding.GetBytes(string.Format("status={0}", Uri.EscapeDataString(content)));
httpWRequest.ContentLength = data.Length;
Stream stream = httpWRequest.GetRequestStream();
stream.Write(data, 0, data.Length);
var response = (HttpWebResponse)httpWRequest.GetResponse();
With this its making a call to Listen method but status parameter is always coming blank. whereas I want the json string {status:"success",payload:"some information"} as parameter.
What am I doing wrong?
P.S.: I tried the below statement as well, while sending the actual content.
byte[] data = encoding.GetBytes(content);
Regards,
M
If do you need to provide any kind of service from MVC tryout WebApi instead. You can use HTTP REST to do this easily.
Read more here ASP.NET WebApi
You appear to be saying the request is json, but sending it using wwwencoding.
Remove the status={0} line bit & just send the json as is.
You can try something like this
using (var sw = new StreamWriter(httpWRequest.GetRequestStream()))
{
sw.Write(content);
sw.Flush();
sw.Close();
}