How to post or get into MVC controller? - angularjs

I have a problem. I have this dropdown list :
#Html.DropDownListFor(m => m.SelectCountryId, Model.Countries, #Translator.Translate("PLEASE_SELECT"), new { id = "CountryID", #class = "form-control",ng_model="countryId", ng_change = "LoadRegions(countryId);", #required = "required" })
And i need on ng_change to get into MVC controller that looks like this:
[AllowAnonymous]
public JsonResult GetRegions(int countryId) // return a JsonResult
{
IUserManager manager = UserFactory.GetUserManager(WebConfiguration.DefaultTerminalId);
var model = manager.GetRegions(countryId);
return Json(model, JsonRequestBehavior.AllowGet);
}
This is script in angular:
$scope.LoadRegions = function (countryId)
{
console.log("COUNTRY ID: ", countryId);
$http.post('/app/Account/GetRegions/'+ countryId).then(function (response)
{
alert(response);
});
}
I get country ID but in console i get this error:
POST http://localhost:60789/app/Account/GetRegions/4 500 (Internal Server Error)

The default routing in MVC allows for {controller}/{action}/{id} but your controller is expecting {controller}/{action}/{countryId}.
You can change your call to look like:
GetRegions?countryId=XXX
Or change your method signature to look like:
public JsonResult GetRegions(int id)
Or, if you really want to, you can accommodate this route in your RouteConfig.cs
Edit: I just realized you're calling this with $http.post but everything in your code suggests you want this to be a GET, so I'd change your angular code to $http.get()

From the looks of it there are a few problems in your javascript.
Try the following.
$scope.LoadRegions = function (countryId)
{
var params = {};
params.countryId = countryId;
console.log("COUNTRY ID: ", countryId);
$http.post('/Account/GetRegions/', params).then(function (response)
{
alert(response);
});
}
As you can see you're passing in the params object with the country ID, you are making a call to the POST on the server side also -> Seperate to the angular app folder.

Related

I send http post request with angular but it does not go to the asp.net mvc action and returns html layout tags

I am doing an angular application with asp.net mvc and i made a registration form with identity, I have layout and index mvc view which i just write in it ng-view tag and i inject html pages in it, I am doing a http post request from angular controller to mvc action method but the request does not go to the mvc action, whereas when i change th views to mvc views and make a templateUrl in angular map to mvc method it works well.
Can any one help me in this problem.
[HttpPost]
[AllowAnonymous]
public async Task<JsonResult> Register(RegisterViewModel model)
{
string message = "";
if (ModelState.IsValid)
{
var user = new ApplicationUser
{
FirstName = model.FirstName,
MiddleName = model.MiddleName,
LastName = model.LastName,
UserName = model.Email,
Email = model.Email,
UserStatus = UserStatus.Waiting
};
var result = await UserManager.CreateAsync(user, model.Password);
if (result.Succeeded)
{
message = "Success";
}
else
{
AddErrors(result);
message = "InvalidEmail";
}
}
else
{
message = "Failed!";
}
return new JsonResult { Data = message, JsonRequestBehavior = JsonRequestBehavior.AllowGet };
}
and this is my angular controller
MyApp.controller('RegisterController', ['$scope','$http',function ($scope, $http) {
$scope.message = '';
$scope.isFormValid = false;
//Check Form Validation
$scope.$watch('f1.$valid', function (newValue) {
$scope.isFormValid = newValue;
});
//Save Data
$scope.SaveData = function (data) {
$scope.submitted = true;
$scope.message = '';
if ($scope.isFormValid) {
$http({
method: 'POST',
url: '/Account/Register',
data: data
}).then(function (response) {
// check your response (if a success status code was resolved)
console.log(response.data);
}, function (error) {
// check your error response
console.log(error);
});
} else {
$scope.message = "Please Fill the blanks";
}
}
}]);
and this is my html page:
<div ng-controller="RegisterController">
<form name="f1" ng-submit="SaveData(user)" novalidate>
controls here
</form
1) Check your browser console for any javascript errors, if you have any, resolve them and try again!
2) Check you have the correct ActionMethodSelectorAttribute attribute ([HttpPost]) over your controller method and that your method name is spelt correctly.
3) Check that you have the correct path in your request.
4) Check you are sending the correct data to the controller!!!
5) Check that the method is public.
6) Check that you are authorised to access that controller/method.
7) Check that you don't have any duplicate method names with either, a) the same parameters and name (if your not using an ActionMethodSelectorAttribute, or b) the same names and method select attributes.
8) Remove all parameters from your method, put a breakpoint at the start of the method, and try making the request and see if it hits the breakpoint. If it works without parameters and not with, then you are not passing the correct required data into the method.
9) Make your request and check the response!! (example below):
// make your request
$http({
method: 'POST',
url: '/Controller/Method',
data: {
foo: bar
}
}).then(function(response) {
// check your response (if a success status code was resolved)
console.log(response);
}, function(error) {
// check your error response
console.log(error);
});
If you have a 404 then your method was not found, if you have a 500 then something blew up in your code, if you have a 401 then you are unauthorised etc... This is really useful to actually know what is going on with your request...
10) Check your application is running!

$http.post request can't find method in controller

I have a AddCategory() method in my Controller:
[RoutePrefix("api")]
public class CategoryController : ApiController
{
....
[Route("addCategory")]
[HttpPost]
public void AddCategory(string category)
{
var getCat = category;
}
At the my Home.html i have button Save New Category i wrote the $http.post method for it:
var testString = "TEST String";
var req = {
method: 'POST',
url: '/api/addCategory',
data: testString,
};
$http(req).then(function successCallback(response) {
console.log("Success");
}, function errorCallback(response) {
console.log("Eror");
});
But i have the next error:
angular.js:11442 POST http://localhost:6059/api/addCategory 404 (Not
Found)
At the Network bookmark in Development console i finded the error:
may be it's important but i disabled XML in WebApiConfig.cs:
var json = GlobalConfiguration.Configuration.Formatters;
json.JsonFormatter.UseDataContractJsonSerializer = true;
json.Remove(json.XmlFormatter);
May be somebody knows how i can change it ? Thanks for your answers!
You method Post need to return IHttpActionResult. or your request http always returns code 404.
Try this :
[RoutePrefix("api")]
public class CategoryController : ApiController
{
....
[Route("addCategory")]
[HttpPost]
public IHttpActionResult AddCategory(string category)
{
var getCat = category;
if(getCat != null)
return Ok();
return NotFound();
}
I advice you to use Api Rest in C# with $resource angular. In my mind, it's the best pattern.
The problem is related to the service you are calling, 404 means not found:
404 http error
therefore something in the service URL or in your local server is not working.

Sending Array of Objects to Web API from AngualrJS

During this process, I grab an array of "vehicles" from the Web API. I modify and do whatever to each vehicle. Then I want to send the list back, without going through and looping...
I've tried a lot of the ways that i've looked up.
I've got this in the WEB API for a breakpoint to see if I can even get the array there, but I havent been able to yet.
public IHttpActionResult UpdateVehicles(Vehicle[] vehiclesArry)
{
return Ok();
}
I'm confused if I need to do a $post, or if I could just "get" it to the correct method like I've been doing. The problem is I can't get the array to the WEB API method.
I've got my $resource setup like this.
return $resource(appSettings.serverPath + "/api/Violators/:id",null,
{
'update': { method: 'PUT' },
'delete': { method: 'DELETE' },
'post': { method: 'POST' }
});
I've tried using $post, but it says the object doesn't support it. I'm not sure what other ways I can try. I've tried using "dynamic" in the web API, that doesn't seem to work either.
You're missing the params object for $resource, so it doesn't know the id.
return $resource(appSettings.serverPath + "/api/Violators/:id", { id: '#id' });
You don't need to explicitly setup methods for get, post, delete. That's already done for you. If your API uses PUT for update, set that up like this:
return $resource(appSettings.serverPath + "/api/Violators/:id", { id: '#id' }, {
update: { method: 'PUT' }
});
Also, the property on your resource must be vehiclesArry exactly or web API won't know how to map it. I also want to echo #sowen. You will need to setup a view model that your endpoint receives.
My assumption is that you are having some script errors in your page or you are not using the $http methods properly.
One problem people usually run into is using the correct url to the web api endpoints in your angular controller. If you don't get it right, you might be getting 404 errors. Look for those in your browser console(network tab)
The below code should work fine without any issues
$http.get("../api/Values/")
.then(function (res) {
var vehicles = res.data;
console.log('data received', JSON.stringify(vehicles));
//Let's update the Name of each vehicle.
$.each(vehicles, function (indx, item) {
item.Name = item.Name + " Updated";
});
console.log('data modified', JSON.stringify(vehicles));
//Let's make a call to web api with modified data
$http.post("../api/Values/UpdateVehicles", vehicles)
.then(function (res2) {
console.log('response', JSON.stringify(res2.data));
});
});
Assuming you have angular js properly loaded in your page and the above code is part of your angular controller for the current page and you have the Web api controller with 2 action methods like below example.
public class ValuesController : ApiController
{
[HttpPost]
[Route("api/Values/UpdateVehicles")]
public IHttpActionResult UpdateVehicles(Vehicle[] vehiclesArry)
{
// just returning whatever came in for TESTING PURPOSE
return Ok(vehiclesArry);
}
public IEnumerable<Vehicle> Get()
{
return new List<Vehicle>
{
new Vehicle {Id = 1, Name = "Car"},
new Vehicle {Id = 2, Name = "Van"}
};
}
}
Also,FYI : I am using Attribute routing in my api controller for the UpdateVehicle endpoint.
Create a model object like
public class UpdateReq
{
public IEnumerable<Vehicle> Vehicles { get; set; }
}
From your angular, just pass a json with an array
{
[v1, v2, v3]
}

angular object post to laravel db

I have a json formatted post that arrives in the laravel api controller :
public function update($id) {
$post=Request::all();
return $post;
}
the post logs out to the console:
{id: 1, title: "Quiz1", description: "This is a quiz", level_id: 1, questions: Array[2]}
I would like to use the $post data in the laravel api controller to extract the data from the json object array and update my database.
The angular post is:
$scope.updateQuiz = function(quiz) {
$scope.loading = true;
$http.put('/admin/api/quiz/' + quiz.id, {
quiz
}).success(function(data, status, headers, config) {
$scope = data;
console.log($scope.quiz);
$scope.loading = false;
});
};
The code works in that it grabs the angular data and posts it to Laravel function and then posts back to the console in the angular app.
It is just the extraction of individual data that I cannot do.
This seems to work for individual posts but is rather cumbersome:
Angular:
$http.put('/admin/api/quiz/' + quiz.id, {
title:quiz.title
}).success......
Laravel Api:
$quiz->title = Request::input('title');
Wondering how I can avoid listing out all post objects.Must be something obvious I'm missing!?
Thanks.
Is this what you want ?
public function update($id) {
$post = Post::find($id);
if( !is_null($post ) ){
$post->title= $request->input('title');
$post->description= $request->input('description');
//And so on for all fields...
$post->save();
}
}
Note : it's not present in my example above, but you should validate the values received with the laravel validation. See http://laravel.com/docs/5.0/validation#form-request-validation
If your question was about how you redirect the http request to the controller, you should read the routing chapter of the doc : http://laravel.com/docs/5.0/routing
ex :
$app->group(['namespace' => 'App\Http\Controllers'], function($group){
$group->put('/admin/api/quiz/', 'YourController#update');
});

actions in $resource in angularjs

I have a webapi back end with the following method in the ProductController :
[HttpGet]
[Route("api/product/FindName")]
public Product FindName(string name){
return name & "Hello "
}
I am trying to make use of $resource in the frontend.
var resource = $resource('api/product/:id', {});
resource.query() will return all items which are exposed in the server side using the GetALL() method. This works fine .
What exactly is the {action} in the $resource does ? I have seen examples for the POST, but what if is set
var resource = $resource('api/product/:id', {}, { FindName: { method: 'GET', params: { name: 'phone' } } });
will this call the method FindName in the backend ? or what exactly it does, I mean the parameter if I set the 'GET' in method.
I am calling as
resource.FindName({ name: 'phone' }, function () {
});
But the backend is not getting fired . i see the call that is being requested to the server from fiddler is
Demo/api/product?name=phone
The resource declaration is incorrect. It should be
var resource = $resource('api/product/:id', {}, { FindName: { method: 'GET', params: { id: 'phone' } } });
This defaults the id placeholder to value phone.
For invocation now you can do
resource.FindName({}, function () { //gets api/product/phone
});
or override id part
resource.FindName({id:'tablet'}, function () { //gets api/product/tablet
});
Resource has a built in GET function that should be able to be used without the need to define the extra FindName action that has been added to $resource.
If you changed the route on your webapi to be
[HttpGet]
[Route("api/product/{name}")]
public Product FindName(string name){
return name & "Hello "
}
Then you could use resource like this to get data back from this route.
var resource = $resource('api/product/:id', {}, {});
resource.get({ id: 'phone' }, function () {
});
If you wanted the name params to match on both you could change :id to :name and in the resource.get change id to name also.
I hope this helps.

Resources