Why page url changes after PUT method in Web API? - asp.net-mvc-4

I am using Web API in a MVC Website. This is my Update action in the API controller:
public HttpResponseMessage PutProduct(int Id, ProductModel model)
{
HttpResponseMessage response = null;
if (ModelState.IsValid)
{
model.ProductId = Id;
if (model.Update())
response = Request.CreateResponse(HttpStatusCode.Created);
}
return response;
}
I call it using JQ AJAX from a partial view which is loaded in the Index.cshtml page. The code works fine and the index page does not get called again, instead, the new list is populated in the partial view itself. I am not calling Index page again. But after the response, the page url changes to show like this:
http://localhost:54820/Products/Index?ProdName=Chicken+Soup&Category=Chinese&Price=20
This is my AJAX:
function updateprod(product) {
$.ajax({
url: uri + '/' + product.ProductId,
type: 'put',
contentType: 'application/json; charset=utf-8',
data: JSON.stringify(product),
statusCode: {
201: function (data) { //accepted
loadlist();
}
}
})
.fail(function (xhr, textStatus, err) {
alert(err);
});
}
I want the URL to be like this, like what it was initially:
http://localhost:54820/Products/Index
Can anyone help ?

You should look at the response headers.
It seems that your response has a location header used by the user-agent to redirect to URL indicated in the response.
Besides that you should use 201 status-code for created resources, for update is better to use 200 (OK), how you can read in the w3c docs.
Hope it helps.

Related

Calling MVC5 action using AXIOS and ValidateAntiForgeryToken

I am trying to call a controller method marked with [ValidateAntiForgeryToken] from my UI using Axios.
I have successfully called the same action by using Jquery ajax
Working AJAX Code.
First i get the token from my form
var addAntiForgeryToken = function (data) {
data.__RequestVerificationToken = $("[name='__RequestVerificationToken']").val();
return data;
};
amd then i call my method
$.ajax({
type: "POST",
url: "http://localhost:40428/controller/action",
data: addAntiForgeryToken({ }),
success: function (response) {
}
});
The above successfully calls the following method in my controller
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Test_Get()
{
ViewBag.Search = true;
return View("Index");
}
What i have already tried with axios is the following
axios({
method: 'post',
url: 'http://localhost:40428/Meeting_Notes/Test_Get',
data: addAntiForgeryToken({})
});
I have also tried setting the headers manually but I still cannot get it to work.
After searching around for a bit I found a simple solution. First create the controller and decorate it with HttpPost and ValidateAntiForgeryToken
[HttpPost]
[ValidateAntiForgeryToken]
public void Test_Axios(int id) { }
Then before calling the controller using axios add the following interceptor for the headers. This will define the header as default for all axios api calls
axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
then retreive the token
var token = document.querySelector('token, input').getAttribute('value');
then use the qs library to stringify the call with the token (Be careful! it's Qs and not qs!)
var request = Qs.stringify({ id: 22, __RequestVerificationToken: token });
if you don't wanna pass any parameters then you can just use the following
var request = Qs.stringify({ __RequestVerificationToken: token });
then just call the controller method
axios({
method: 'post',
url: "/controller/Test_Axios",
data: request
});
And you are done! You can now start calling mvc 5 controller, decorated with the [ValidateAntiForgeryToken] attribute.

posting object from angular 2 application to Web Api application (getting Unsupported Media Type)

I could use some guidens, sending an object from my angular 2 application to the Web API.
I know how to GET objects from the Web Api, to my angular 2 application, but can't seem to figure out how the post method works or even if I should use the http.post methodd.
My angular 2 application has the following method:
sendUpdatdReservation(updatedReservation: Reservation) {
var result;
var objectToSend = JSON.stringify(updatedReservation);
this.http.post('http://localhost:52262/api/postbookings', objectToSend)
.map((res: Response) => res.json()).subscribe(res => result = res);
console.log(result);
}
The "updatedReservation" is an object, which I convert to JSON.
The Web api can be reached by the following address:
httl://localhost:52262/api/postbookings
Web Api controller:
[EnableCors(origins: "*", headers: "*", methods: "*")]
public class PostBookingsController : ApiController
{
[AcceptVerbs()]
public bool ConfirmBooking(Booking booking)
{
return true;
}
}
What I'm trying to do is to send the object, update my database based on the changes values that the object has. Then send back true or false if this is a confirmation or not so I can redirect to confirmation page.
Do any know the unsupported media type error?, is that related to that the object i send is not what the api method expects?
Hope someone can help.
You need to set the Content-Type header when sending the request:
sendUpdatdReservation(updatedReservation: Reservation) {
var result;
var objectToSend = JSON.stringify(updatedReservation);
var headers = new Headers();
headers.append('Content-Type', 'application/json');
this.http.post('http://localhost:52262/api/postbookings', objectToSend, { headers: headers })
.map((res: Response) => res.json()).subscribe(res => {
this.result = res;
console.log(this.result);
});
}
Don't forget to import this class:
import {Http,Headers} from 'angular2/http';

Nodejs / Express Redirect after POST

I'm trying to rebuild an app based from PHP to MEAN and I've tried integrating a 3rd party payment gateway where users can enter their credit card info.
I was able to create a post request using the 'request' module and received a response status code 200 from the third party. Now that the request is fulfilled is there a way to redirect the user to the third party's site (similar to a POST request done with html forms and PHP)?
Here's the code block of the post request
function(req, res) {
request({
url: 'https://urlopaymentgateway',
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
form:data,
followAllRedirects:true
},function(error,response,body){
if(error) {
console.log("FAIL");
console.log(error);
} else {
console.log(response.statusCode);
/* How to do redirection here? */
}
});
}
After further reading, the followAllRedirects work only if the status code is between 300 and 400.
I'm fairly new to node, but this works for me.
router.post('/some_path/', function(req, res) {
res.status(200).send('<html><body></body><script type="text/javascript">window.location.href="/some_new_path";</script></html>');
});
You can make redirects via res.redirect(), http://expressjs.com/api.html#res.redirect
Also, you may want to get redirected url from your POST request, here is it
function(error,response,body){
if(error) {
console.log("FAIL");
console.log(error);
} else {
console.log(response.statusCode);
var url = response.request.href
res.redirect(url)
}

Calling POST as URL ASP.NET web api

I want to know how to test POST by typing in the url.
Here's my route Config
config.Routes.MapHttpRoute(
name: "myWebApi",
routeTemplate: "api/mywebapi/{action}/{ID}/{DeptID}",
defaults: new { Controller = "mywebapi", ID = #"\d+", DeptID = #"\d+" }
);
programmatically this is how I call POST
I have 3 text boxes and a button. When user clicks on the button the below program gets called
function parseform(button) {
var id = $("#ID").val();
var deptid = $("#DeptID").val();
var name = $("#Name").val();
var inputdata = {
id: id,
deptid: deptid,
name: name
}
if (button.attr('value') === "POST") {
postdata(inputdata);
} else {
console.log("ERROR");
}
}
function postdata(inputdata) {
$("#response").text("Posted");
$.ajax({
type: "POST",
dataType: "json",
url: "api/mywebapi/Post/",
contentType: "application/json",
data: JSON.stringify(inputdata),
xhrFields: {
withCredentials: true
},
success: function (data, status, xhr) {
$("#response").text(status+" - "+data)
},
error: function (xhr, status, error) {
var json = jQuery.parseJSON(xhr.responseText);
$("#response").text(status)
}
});
}
In the controller
[System.Web.Http.AcceptVerbs("POST")]
public void Post([FromBody]mywebapi value)
{
saves to database
}
Here's what I tested
http://localhost:222/api/mywebapi/Post/new newwebapi ({"id":"1","deptid":"2","name":"testing"})
I get error. How to test this?
thanks
R
Since it's a POST request, you can't test it in your browser by typing in an address (those are GET requests, which contain no body).
To test these types of things you can use something like Postman
or Rest Console (if you're using chrome), there's tons of these types of things in whatever your browsers extension store is called.
Some tools you can use are something like Fiddler
this will let you see what the requests and responses look like, and you can change/modify them as well, though it's probably a bit harder to use than something like PostMan or Rest Console (also more powerful)

How to return partial view or Json result based on condition?

I have following code in the controller, here I want to return Partial View or Json Result to jquery. My problem is when this controller is hit jquery blocks the UI with some progress bar and waiting for response until it return. But when ModelState is false it return partial view which bypass jquery unblock UI. So this makes UI block forever.
[HttpPost]
public ActionResult Edit(Form form)
{
...
if (!ModelState.IsValid)
{
return PartialView("EditPartial", model);
}
return Json(new
{
Success = true,
Id = ID
});
}
How can I solve this problem?
Your controller method is behaving properly. You just need to modify your ajax call:
$.ajax({
url: '<your url>',
dataType: 'json',
success: function(data, textStatus, jqXHR) {
// You have the json result.
},
error: function(jqXHR, textStatus, errorThrown) {
// You have the partial view
}
});
An empty response is also is considered to be a failed json parse. Your controller method should either return a response of null or {} instead.
See the below url for more details of dataType and error
http://api.jquery.com/jQuery.ajax/