why is PUT not being recognized in controller? - asp.net-mvc

I am trying to update a customers feedback post, the POST & DELETE work but I have been stuck on the PUT for a couple of days. any help will be great. thanks
Factory
app.factory('Post', function ($resource) {
return $resource('/api/apiPost/:id',
{ id: '#id' },
{ 'save': { method: 'POST' } },
{ 'update': { method: 'PUT' } },
{ 'query': { method: 'GET', isArray: false } });
});
CONTROLLER
$scope.updatePost = function (post) {
//alert("WORKS");
Post.update({ id: post.PostId }, $scope.post, function () {
$scope.postArray.push(post);
$scope.post = {
Title: '',
Body: ''
};
}, function () { });
}
ADAPTER
public Post PutNewPost(int id, Post newPost)
{
Post post = new Post();
post.PostId = newPost.PostId;
post.Title = newPost.Title;
post.Body = newPost.Body;
post.Hidden = newPost.Hidden;
db.Posts.Add(post);
db.SaveChanges();
return db.Posts.FirstOrDefault();
}
API CONTROLLER
// PUT api/<controller>/5
[Authorize(Roles = "Admin")]
public IHttpActionResult Put(int id, [FromBody]Post newPost)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
return Ok(_adapter.PutNewPost(id, newPost));
}
ERROR MESSAGE
TypeError: undefined is not a function
at h.$scope.updatePost (https://localhost:44301/MyScripts/AjaxPostController.js:40:14)
at https://localhost:44301/Scripts/angular.min.js:169:382
at https://localhost:44301/Scripts/angular.min.js:186:390
at h.$eval (https://localhost:44301/Scripts/angular.min.js:108:40)
at h.$apply (https://localhost:44301/Scripts/angular.min.js:108:318)
at HTMLInputElement.<anonymous> (https://localhost:44301/Scripts/angular.min.js:186:372)
at HTMLInputElement.o.event.dispatch (https://localhost:44301/Scripts/jquery-2.1.0.min.js:3:6055)
at HTMLInputElement.r.handle (https://localhost:44301/Scripts/jquery-2.1.0.min.js:3:2830)

I think your method arguments for $resource are mistaken. Return all your custom methods in 1 object like this:
app.factory('Post', function ($resource) {
return $resource('/api/apiPost/:id',
{ id: '#id' },
{
'save': { method: 'POST' },
'update': { method: 'PUT' },
'query': { method: 'GET', isArray: false }
}
);

Related

Kendo Grid CRUD operations

I'm using a Kendo (for jQuery) Grid in an MVC Core project with Add, Edit, Delete using ajax JSON and SQL Server, but the Update, Destroy and Create actions are not called.
Here is my view:
<div id="grid" class="k-rtl applicationFontLight"></div>
<script>
$(document).ready(function () {
dataSource = new kendo.data.DataSource({
transport: {
read: {
url: "/Persons/Read",
dataType: "json"
},
update: {
url: "/Persons/Update",
dataType: "json"
},
destroy: {
url: "/Persons/Destroy",
dataType: "json"
},
create: {
url: "/Persons/Create",
dataType: "json"
},
parameterMap: function (options, operation) {
if (operation !== "read" && options.models) {
return { models: kendo.stringify(options.models) };
}
}
},
batch: true,
pageSize: 20,
schema: {
model: {
id: "id",
fields: {
Id: { editable: false, nullable: true },
firstName: {
type: "string",
validation: {
required: {
message: "Required"
}
}
},
lastName: {
type: "string",
validation: {
required: {
message: "Required"
}
}
},
birthDate: {
type: "string",
validation: {
required: {
message: "Required"
}
}
}
}
}
}
})
$("#grid").kendoGrid({
dataSource: dataSource,
pageable: true,
toolbar: [{ name: "create", text: "New" }],
columns: [
{ field: "firstName", title: "Name", width: "80px" },
{ field: "lastName", title: "Last Name", width: "120px" },
{ field: "birthDate", title: "Birth Date", width: "80px" },
{
command: [{
name: "edit",
text: {
edit: "Edit",
update: "Update",
cancel: "Cancel"
}
}
, {
name: "destroy",
text: "Delete"
}
], width: "200px"
}
],
editable: "inline"
});
});
</script>
And my Controller Code:
public class PersonsController : Controller
{
private readonly DataContext _context;
public PersonsController(DataContext context)
{
_context = context;
}
// GET: Persons
public ActionResult Index()
{
return View();
}
public ActionResult Read()
{
var persons = _context.Persons.ToList();
return Json(persons);
}
public async Task<IActionResult> Create([Bind("Id,FirstName,LastName,BirthDate")] Person person)
{
if (ModelState.IsValid)
{
_context.Add(person);
await _context.SaveChangesAsync();
return Json(person);
}
return View(person);
}
public async Task<IActionResult> Update(int id, [Bind("Id,FirstName,LastName,BirthDate")] Person person)
{
if (id != person.Id)
{
return NotFound();
}
if (ModelState.IsValid)
{
try
{
_context.Update(person);
await _context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!PersonExists(person.Id))
{
return NotFound();
}
else
{
throw;
}
}
return Json(person);
}
return View(person);
}
[ValidateAntiForgeryToken]
public async Task<IActionResult> Destroy(int id)
{
var person = await _context.Persons.FindAsync(id);
_context.Persons.Remove(person);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
private bool PersonExists(int id)
{
return _context.Persons.Any(e => e.Id == id);
}
}
The other actions (besides the Read action) are not called and give me this error in the browser console:
Unexpected character encountered while parsing value: m. Path '', line 0, position 0.
or view Destroy not found...
Replace the following code:
command: [{
name: "edit",
text: {
edit: "Edit",
update: "Update",
cancel: "Cancel"
}
}
, {
name: "destroy",
text: "Delete"
}
], width: "200px"
Try the default column command, then try the toolbar create.
command: ["edit","destroy"], title: " ", width: "200px"

How to access Customer table's data in nopcommerce

I want to show Customer table's data of nopcommerce in admin page.
i did write a plugin for that and receive data in controller but in view i have a problem and show me error happened message.
here is my controller code:
public class UserDetailsController : BasePluginController
{
private ICustomerService _UserDetail;
public UserDetailsController(ICustomerService UserDetail)
{
_UserDetail = UserDetail;
}
public ActionResult Manage()
{
return View();
}
[HttpPost]
public ActionResult GetUsers(DataSourceRequest userDetail)
{
var details = _UserDetail.GetAllCustomers();
var gridModel = new DataSourceResult
{
Data = details,
Total = details.Count
};
return Json(gridModel);
}
}
And this is my view code:
#{
Layout = "~/Views/Shared/_AdminLayout.cshtml";
}
<script>
$(document).ready(function() {
$("#user-details").kendoGrid({
dataSource: {
type: "json",
transport: {
read: {
url: "#Html.Raw(Url.Action("GetUsers", "UserDetails"))",
type: "POST",
dataType: "json",
},
},
schema: {
data: "Data",
total: "Total",
errors: "Errors",
model: {
id: "Id",
}
},
requestEnd: function(e) {
if (e.type == "update") {
this.read();
}
},
error: function(e) {
display_kendoui_grid_error(e);
// Cancel the changes
this.cancelChanges();
},
serverPaging: true,
serverFiltering: true,
serverSorting: true
},
pageable: {
refresh: true,
numeric: false,
previousNext: false,
info:false
},
editable: {
confirmation: true,
mode: "inline"
},
scrollable: false,
columns: [
{
field: "Email",
title: "User Name",
width: 200
},
{
command: [
{
name: "edit",
text: "#T("Admin.Common.Edit")"
}, {
name: "destroy",
text: "#T("Admin.Common.Delete")"
}
],
width: 200
}
]
});
});
</script>
<div id="user-details"></div>
can anybody help me?
Change your GetUsers method on this way:
var details = _UserDetail.GetAllCustomers();
var gridModel = new DataSourceResult
{
Data=details.Select(x=>
{
return new UserDetail()
{
Email= x.Email
};
}),
Total = details.Count(),
};
return Json(gridModel);

Use a factory in AngularJS

When a button is clicked, I want to create a new User, and redirect the person to http://www.myapp.com/#/user/134.
The below code works, but am I using AngularJS factories correctly? It feels strange to have to define a 'createUser' function in my controller.
myApp.factory('User', ['$resource', function($resource) {
return $resource("/users/:id", { id: "#id" },
{
'create': { method: 'POST' },
'index': { method: 'GET', isArray: true },
'show': { method: 'GET', isArray: false },
'update': { method: 'PUT' },
'destroy': { method: 'DELETE' }
}
);
}]);
myApp.controller('splash', ['$scope', '$http', '$location', 'User', function($scope, $http, $location, User){
$scope.createUser = function(){
User.create(
{},
function(response){
$scope.user = response;
$location.path('/users/' + $scope.user.id);
},
function(){
console.log('error creating user');
});
}
}]);
Here is a view with a button for creating a new user:
<button ng-click="createUser()">Create User</button>

Populating a Webgrid from an Ajax Call

I have a problem with populating a Webgrid from an Ajax call.
I have followed the example as showed in the following thread: mvc3 populating bind webgrid from ajax however, that did not yield any results.
When I run the website, I always get the message: "Error: undefined".
when debugging the code, I am quite sure that the problem lies in the fact that the return PartialView is the problem, as my data object in the ajax success method does not get filled with data.
Here are the examples of my code:
Ajax call:
$.fn.getCardResult = function (leerling, kaart) {
$.ajax({
type: "GET",
url: '#Url.Action("GetResults","Kaarten")',
data: { leerlingID: leerling, cardID: kaart },
cache: false,
success: function (data) {
console.log(data);
if (!data.ok) {
window.alert(' error : ' + data.message);
}
else {
$('#card').html(data);
}
}
});
}
Partial View call:
<div class="card-content" id="card">
#{
if(Model.Kaart != null && Model.Kaart.Count > 0)
{
#Html.Partial("_Kaarten")
}
else
{
#: Er zijn geen kaarten beschikbaar.
}
}
</div>
Partial View:
#model List<ProjectCarrousel.Models.KaartenModel>
#{
var grid = new WebGrid(source: Model,ajaxUpdateContainerId: "card",
defaultSort: "Topicname");
grid.GetHtml(
tableStyle: "webgrid",
columns: grid.Columns(
grid.Column("Topicname", "Topic"),
grid.Column("Taskname", "Taken"),
grid.Column("Taskpoints", "Punten"),
grid.Column("Grades", "Resultaat"),
grid.Column("Date", "Datum"),
grid.Column("Teachercode", "Paraaf Docent")
)
);
}
Controller code:
public ActionResult GetResults(int leerlingID, string cardID)
{
try
{
int Ovnumber = leerlingID;
string CardId = cardID;
List<KaartenModel> kaartlijst = new List<KaartenModel>();
IEnumerable<topic> topics = _db.topic.Include("tasks.studenttotask").Where(i => i.CardID == CardId);
foreach (topic topic in topics)
{
foreach (tasks task in topic.tasks)
{
KaartenModel ka = new KaartenModel();
ka.Topicname = task.topic.Topicname;
ka.Taskname = task.Taskname;
ka.Taskpoints = task.Taskpoints;
ka.Ranks = task.Ranks;
ka.Date = task.studenttotask.Where(i => i.Ovnumber == Ovnumber).Select(d => d.Date).SingleOrDefault();
ka.Grades = task.studenttotask.Where(i => i.Ovnumber == Ovnumber).Select(d => d.Grades).SingleOrDefault();
ka.Teachercode = task.studenttotask.Where(i => i.Ovnumber == Ovnumber).Select(d => d.Teachercode).SingleOrDefault();
kaartlijst.Add(ka);
}
}
KVM.Kaart = kaartlijst;
return PartialView("_Kaarten", KVM.Kaart);
}
catch (Exception ex)
{
return Json(new { ok = false, message = ex.Message });
}
}
If anyone could help it would be greatly appreciated.
UPDATE
After fiddling about a bit I found a solution that worked for me. Below is a snippet of an updated Ajax Call:
The solution I found was too make the Success method in another way. This made sure that the Partial View rendered properly. Below is the Ajax call snippet.
$.ajax({
url: '#Url.Action("GetAjaxCall","Home")',
contentType: 'application/html; charset=utf-8',
type: 'GET',
dataType: 'html',
data: { id: id },
})
.success(function (result) {
$('#sectionContents').html(result);
})
.error(function (xhr, status) {
alert(xhr.responseText);
});
The solution I found was too make the Success method in another way. This made sure that the Partial View rendered properly. Below is the Ajax call snippet.
$.ajax({
url: '#Url.Action("GetAjaxCall","Home")',
contentType: 'application/html; charset=utf-8',
type: 'GET',
dataType: 'html',
data: { id: id },
})
.success(function (result) {
$('#sectionContents').html(result);
})
.error(function (xhr, status) {
alert(xhr.responseText);
});

Unable to bind JSON data to KendoUI Grid

I am facing a certain issue while trying to bind the KendoUi Grid with the Json data from the controller. Things seem fine and my Json object contains data but still grid is not showing any thing:
And I am getting this error in chrome JavaScript console:
GET http://localhost:8084/Records?take=5&skip=0&page=1&pageSize=5 500 (Internal Server Error)
In View:
<div id="grid">
</div>
<div>
<script type="text/javascript">
$(document).ready(function () {
$("#grid").kendoGrid({
dataSource: {
type: "json",
serverPaging: true,
pageSize: 5,
groupable: true,
selectable: "row",
transport: { read: { url: "Records", dataType: "json"} }
},
height: 400,
scrollable: true,
sortable: true,
filterable: true,
pageable: true,
columns: [
{ field: "No", title: "No" },
{ field: "Desc", title: "Description" },
{ field: "priority", title: "Priority" },
{ field: "decision", title: "Decision" }
],
dataBound: function () {
this.expandRow(this.tbody.find("tr.k-master-row").first());
}
});
});
</script>
In Controller:
public ActionResult GetRecords()
{
var obj = new User();
var jsnRslt = obj.GetResult(Session["id"].ToString());
//return Json(jsnRslt);
return Json(jsnRslt, JsonRequestBehavior.AllowGet); //Changed as suggested by Dismissile
}
In Model:
public object GetResult(string usrId)
{
…
….
….. try
{
int i = 0;
if (rcrds != null || rcrds.HasRows)
{
jsonWriter.WriteStartObject();
while (rcrds.Read())
{
for (int j = 0; j < rcrds.FieldCount; j++)
{
jsonWriter.WritePropertyName(rcrds.GetName(j));
jsonWriter.WriteValue(rcrds.GetValue(j));
}
i++;
}
jsonWriter.WriteEndObject();
}
}
catch (Exception ex) { }
return jsonWriter;
}
}
Kindly help.
You probably need this in your JSON call:
return Json(jsnRslt, JsonRequestBehavor.AllowGet);
It looks like you are doing a GET call, and by default GET is not allowed on a JSON call.
Try to use the transport attribute within dataSource, something like this:
<script type="text/javascript">
var dataSource = new kendo.data.DataSource({
batch: true,
schema: {
model: {
id: "EmployeeID",
fields: {
EmployeeID: { editable: true, validation: { required: true } },
EmployeeName: { validation: { required: true } }
}
}
},
transport: {
read: {
url: "/Home/GetData",
type: "GET"
},
update: {
url: "/Home/Update",
type: "POST",
contentType: 'application/json'
},
destroy: {
url: "/Home/Destroy",
type: "POST",
contentType: 'application/json'
},
create: {
url: "/Home/Create",
type: "POST",
contentType: 'application/json'
},
pageSize: 1,
parameterMap: function (options, operation) {
if (operation !== "read" && options.models) {
return kendo.stringify(options.models) ;
}
}
}
});
$(document).ready(function () {
$("#grid").kendoGrid({
dataSource: dataSource,
navigatable: true,
pageable: true,
height: 430,
sortable: true,
toolbar: ["create", "save", "cancel"],
columns: [
{ field: "EmployeeID", title: "Employee ID", width: 110 },
{ field: "EmployeeName", title: "Employee Name", width: 110 },
{ command: "destroy", title: "Delete", width: 90 }],
editable: true,
selectable: "multiple row",
groupable: true,
navigatable: true,
filterable: true
});
});
</script>
The controller:
public class HomeController : Controller
{
//
// GET: /Home/
public ActionResult Index()
{
var employee = new Employee().GetEmployeeList();
return View(employee);
}
[AcceptVerbs(HttpVerbs.Get)]
public JsonResult GetData()
{
var obj = new Employee();
return Json(obj.GetEmployeeList(), JsonRequestBehavior.AllowGet);
}
[HttpPost]
public JsonResult Update(List<Employee> model)
{
var obj = new Employee();
//return View();
return Json(obj);
}
[HttpPost]
public JsonResult Create(List<Employee> model)
{
var obj = new Employee();
return Json(obj);
}
public ActionResult Destroy(Employee model)
{
return View();
}
}
Return a html view from index method to hold the grid &
I think you also need to add a datasource request in your ActionMethod Parm
public ActionResult GetResult([DatasourceRequest]request, string usrId)
return Json(jsnRslt.ToDatasourceResult(request), JsonRequestBehavior.AllowGet);
Every kendogrid needs this
Try this
transport: { read: { url: "Records", dataType: "jsonp"} }
try with jsonp instead of json.
You are returning an ActionResult, it should be a JsonResult instead.

Resources