POST method for Valence API - desire2learn

I am facing an issue in creating a new user through valence api.
var request = new RestRequest(string.Format("/d2l/api/lp/{0}/users", LP_VERSION));
request.Method = Method.POST;
request.RequestFormat = DataFormat.Json;
request.AddBody(user);
authenticator.Authenticate(client, request);
var response = client.Execute<UserData>(request);
So I create a POST request and pass object as JSon . But in Response, userData is not been retrieved and the StatusCode is coming as Not Found.
My question is : Why am I getting a 'Not found' status when I try to create a new user?
Any help will be appreciated.

The API route to create a user has a trailing slash: POST /d2l/api/lp/(version)/users/. In general, the Valence Learning Framework API uses a trailing slash to call out a resource that's a collection of items, and in general to create a new single entity, you do a POST to the collection that aggregates those entities.

No need to reply. Fortunately, I figured it out. The answer is that you should not pass a Serialized Json block to the request body. The code "request.AddBody(user) should be only just a "User" object class. Thanks anyway.

Related

Previous GET parameters being unintentionally preserved in POST request

As of current I navigate to a view using a GET request, looking something like this:
/batches/install?Id=2&ScheduledDate=07.29%3A12
From there, I send a POST request using a form (where I include what data I wish to include in the request.
Furthermore I set the forms action to "Create" which is the action I wish to send the request to.
My issue is the fact that sending this request keeps the GET arguments in the POST url, making it look the following:
../batches/Create/2?ScheduledDate=07.29%3A12
I do not want this since:
1: it looks weird
2: it sends data I do not intend it to send in this request
3: if my model already has a property named "id" or "scheduledDate" the unintentional GET parameters will get bound to those properties.
How can I ignore the current GET parameters in my new POST request?
I just want to send the form POST data to the url:
../batches/create
(without any GET parameters)
How would this be done?
As requested, here is my POST form:
#using (var f = Html.Bootstrap().Begin(new Form("Create")))
{
//inputs omitted for brevity
#Html.Bootstrap().SubmitButton().Style(ButtonStyle.Success).Text("Create batch")
}
Note that I use the TwitterBootstrapMVC html helpers (https://www.twitterbootstrapmvc.com/), althought this really shouldn't matter.
As requested, to sum up:
I send a get request to : /batches/install?Id=2&ScheduledDate=07.29%3A12.
Through the returned view I send a POST request to: /batches/create.
However the previous get parameters get included in the POST request URL making the POST request query: /batches/Create/2?ScheduledDate=07.29%3A12 (which is NOT intended).
This is not a great Idea though, but will give you what you want.
[HttpPost]
public ActionResult Create() {
//do whatever you want with the values
return RedirectToAction("Create", "batches");
}
This is a "Feature" of MVC that was previously reported as a bug (issue 1346). As pointed out in the post, there are a few different workarounds for it:
Use named routes to ensure that only the route you want will get used to generate the URL (this is often a good practice, though it won't help in this particular scenario)
Specify all route parameters explicitly - even the values that you want to be empty. That is one way to solve this particular problem.
Instead of using Routing to generate the URLs, you can use Razor's ~/ syntax or call Url.Content("~/someurl") to ensure that no extra (or unexpected) processing will happen to the URL you're trying to generate.
For this particular scenario, you could just explicitly declare the parameters with an empty string inside of the Form.
#using (var f = Html.Bootstrap().Begin(new Form("Create").RouteValues(new { Id = "", ScheduledDate = "" })))
{
//inputs omitted for brevity
#Html.Bootstrap().SubmitButton().Style(ButtonStyle.Success).Text("Create batch")
}

Get the body of a POST request in an MVC Controller Action

I have a WebJob that is posting a JSON object to a controller in my MVC website.
The default ModelBinder is not working correctly in this instance. Rather than troubleshoot the binder, I am perfectly happy to handle the serialization myself.
How do I get the body of the POST request from my controller Action so that I can feed it into JSON.net?
I have tried using a StreamReader on Request.InputStream, but I get an empty string.
I'm using Angular.js $http.Post() to send a json object to my actionresult, and the Model Binding was failing. I used the below code and was able to get the json object posted and then use Newtonsoft for the DeSerialization. Interesting thing is that Newtonsoft didn't throw an error on Deserialization while the default model binding in MVC did.
var req = Request.InputStream;
var json = new StreamReader(req).ReadToEnd();
var result = JsonConvert.DeserializeObject<Model>(json);

How to get the raw binary content in Grails controller

after many days of search and many unsuccessful tries, I hope that the community knows a way to achieve my task:
I want to use grails as a kind of a proxy to my solr backend. By this, I want to ensure that only authorized requests are handled by solr. Grails checks the provided collection and the requested action and validated the request with predefined user based rules. Therefore, I extended my grails URL mapping to
"/documents/$collection/$query" {
controller = "documents"
action = action = [GET: "proxy_get", POST: "proxy_post"]
}
The proxy_get method works fine even when the client is using solrJ. All I have to to is to forward the URL request to solr and to reply with the solr response.
However, in the proxy_post method, I need to get the raw body data of the request to forward it to solr. SolrJ is using javabin for that and I was not able so far to get the raw binary request. The most promising approach was this:
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(solrUrl);
InputStream requestStream = request.getInputStream();
ContentType contentType = ContentType.create(request.getContentType());
httpPost.setEntity(new ByteArrayEntity(IOUtils.toByteArray(requestStream), contentType));
httpPost.setHeader("Content-Type", request.getContentType())
HttpResponse solrResponse = httpClient.execute(httpPost);
However, the transferred content is empty in case of javabin (e.g. when I add a document using solrJ).
So my question is, whether there is any possibility to get to the raw binary post content so that I can forward the request to solr.
Mathias
try using Groovy HttpBuilder. It has a powerful low-level API, while providing groovyness

HMAC with ASP.NET WebAPI using Cuong's Solution

I spent a some time today looking through various HMAC implementations in C# for an upcoming WebAPI project. I wanted to start out with some existing code just to see it all work and understand it better before I either wrote it from scratch or modified it for my needs.
There are a bunch of great articles and posts both here and on the web. However, I have gotten to the point that I need some pointers and would greatly appreciate some insight.
I started with Cuong's post here: How to secure an ASP.NET Web API.
I knew I would have to expand upon it since I wanted to support both json and formencoded data. My test client is also written in C# using HttpClient and I spun up an empty WebAPI project and am using the ValuesController.
Below are my observations and questions:
POSTing: In order to get Cuong's code to work (validate successfully), my POST needs to include the parameters in the URL, however in order to get the values to my controller, I need to include them in the body. Is this normal for this type of authentication? In this particular instance, the message I am hashing is http://:10300/api/values?param1=value1&param2=value2. Now I can parse the query string manually to get them, however in order to get the value to my controller through binding, I must also:
var dict = new Dictionary<string, string>
{
{"param1", "value1"},
{"param2", "value2"}
};
var content = new FormUrlEncodedContent(dict);
var response = await httpClient.PostAsync(httpClient.BaseAddress, content);
Otherwise my parameter is always null in the post action of the ValuesController.
I am planning on expanding the code to include a nonce. Between the combination of a nonce, a timestamp and the verb, is that enough for a secure hash? Is there really a need to also hash the message?
I tried (very unsuccessfully) to extend the code to support json as well as form encoded data and I must be missing something obvious.
Cuong is using the Authentication and Timestamp headers instead of putting the signature and timestamp in the query string. Is there a benefit to one method over the other? The majority of articles I have read have them in the query string itself.
The code looks great and I am a little out of my element here. I might be safer (saner?) just writing it from scratch to appreciate the nuances of it. That said, if anyone can lend some insight into what I am seeing that would be great.
At the end of the day, I want to be able to use the built in authorization mechinism of the WebAPI framework to simply attribute the methods/controllers, be able to accept form encoded and json data and reasonably model bind for complex types.
* Update *
I have done some more work today and below is the code from my nUnit PostTest. I figured out how to get the values through without both including them in the body and the query string (code below).
[Test]
public async void PostTest()
{
using (var httpClient = new HttpClient())
{
var payload = new FormUrlEncodedContent(new Dictionary<string, string>
{
{"key1", "value1"},
{"key2", "value2"}
});
var now = DateTime.UtcNow.ToString("U");
httpClient.BaseAddress = new Uri(string.Format("http://ipv4.fiddler:10300/api/values"));
httpClient.DefaultRequestHeaders.Add("Timestamp", now);
httpClient.DefaultRequestHeaders.Add("Authentication", string.Format("test:{0}", BuildPostMessage(now, httpClient.BaseAddress, await payload.ReadAsStringAsync())));
var response = await httpClient.PostAsync(httpClient.BaseAddress, payload);
await response.Content.ReadAsStringAsync();
Assert.AreEqual(true, response.IsSuccessStatusCode);
}
}
I also figured out the model binding portion of it. There is a great article here: http://www.west-wind.com/weblog/posts/2012/Mar/21/ASPNET-Web-API-and-Simple-Value-Parameters-from-POSTed-data that explains how POST works and I was able to get it to work with both a model of my own design as well as with the FormDataCollection object.
Now I am left wondering whether or not it is worth adding json encoded messages or if standardizing on FormUrlEncoding is the way to go. Also, are client nounce's enough or should I implement a server side nounce? Does a server side nounce double all of the calls to the service (first one throws a 401, second one includes the payload with the nounce?

WebResponse to HttpResponseBase. Is it possible?

In a controller action, I am manually sending a form to a remote URL using WebRequest. I successfully receive a WebResponse containing an html page to display. I would like to "paste" this response as the Response (of type HttpResponseBase) of the action. An action normally returns an ActionResult, so how do I conclude my controller action so that the WebResponse will be the result?
Note: the Url in the browser must also become the url of the response.
Update: Here is the goal. This is on a paypal checkout page. Instead of having a form with all cart hidden fields and a checkout submit button in my view, I would like a simple checkout button linked to one of my actions. In this action, I will prepare the WebRequest with the form and send it to paypal. Doing this in an action also allows me to store the inactivated order in a DB table so that when the order confirmation comes I can compare it with the stored order and activate it.
Solution: thanks to those who answered for pointing out that this would not be possible to redirect with a POST. It appears that I am not obliged to redirect to paypal with a POST. Instead I can construct a URL with all the cart data in the query string and redirect to it. Doing it from a controller action method still allows me to store the pending order in a database.
Thanks
If you just want the content of the WebRequest response to be sent back in the response from your controller action, you could do something like this in your action method:
WebRequest req = WebRequest.Create("http://www.google.com");
WebResponse res = req.GetResponse();
StreamReader sr = new StreamReader(res.GetResponseStream());
ContentResult cr = new ContentResult();
cr.Content = sr.ReadToEnd();
return cr;
this is even more concise:
WebRequest req = WebRequest.Create("http://www.google.com");
WebResponse res = req.GetResponse();
FileStreamResult fsr = new FileStreamResult(res.GetResponseStream(),res.ContentType);
return fsr;
THere is no direct way to do this. I dont know much about ASp.NET. ARe you saying that your ASP.net page is doing a HTTP request to a remote site, and getting back a response, and you want that response to become a HTTPResponseBase? What do you want to do with it after that?
See the following SO thread on a similar topic...
How do I mock HttpResponseBase.End()?

Resources