Call Controller from .cshtml via getJSON - javascript

I have performed this action within a .js file without issue and I am wondering if I have to do something a little different from a .cshtml because I can't seem to find any other reason this is failing. Here is my js within my .cshtml file:
mergeBtn.onclick = function (e) {
e.preventDefault();
var url = '/api/publicpatron/student-no-validation?studentNo=' + studentNo.value;
$.getJSON(url)
.done(function (json) {
if (json.errors) {
toastr.error(json.message, '', { timeOut: 0, extendedTimeOut: 0 })
}
else {
//do something
}
})
.fail(function (jqxhr, textStatus, error) {
var err = textStatus = ', ' + error;
toastr.error(err, '', { timeOut: 0, extendedTimeOut: 0 })
})
}
The code in the controller doesn't seem to be the issue as it never gets to the controller, I have verified I have the controller file name and function name correct in my URL. Any suggestions? Is this not possible from within a .cshtml file??
UPDATE:
Here is the controller:
file name: PublicPatronController
[Authorize(Roles = "my-roles")]
[ActionName("student-no-validation")]
public dynamic IsStudentNoValid([FromUri] string studentNo)
{
dynamic results = new ExpandoObject();
if (studentNo == null)
{
results.error = true;
results.message = "Invalid Student Number";
return results;
}
using (ADRoutineEntities db = new ADRoutineEntities())
{
var exists = db.UserLinkages.Any(x => x.StudentNo == studentNo);
if (!exists)
{
results.errors = true;
results.message = string.Format("Student number {0} does not exist", studentNo);
return results;
}
}
results.ok = true;
return results;
}
UPDATE 2:
It does appear to be related to the controller somehow. I changed the url to a different apicontroller I use elsewhere and it worked fine. The issue seems to be related to the name of the apicontroller. When I change it to the name of an existing apicontroller but keep the actionname the same it works. Why would that be???

You should add the [HttpGet]-attribute to the method on the controller.
Normally WebAPI takes the first part of the methodname to determine what HTTP-verb it should use. In your case, that's not a valid http-method, so you need to explicitly add the attribute.
Another option is to change the method name, eg: GetIsStudentNoValid
You should also return an HttpResponseMessage with a status code instead of a dynamic

Related

GUID model binding in ASP.NET MVC

I was hoping someone could help me sort this out.
The solution to this is probably obvious but I can't seem to figure out what I'm missing...
I'm trying to issue a get request from my Javascript code, and the URL contains a Guid.
The ASP.NET controller does not get hit/register the request to the API.
I've tried a couple different things already but this is my Javascript and Controller as is:
function getChat( contact_id ) {
$.get("/contact/conversations", { contactId: contact_id })
.done( function(resp) {
let chat_data = resp.data || [];
loadChat( chat_data );
});
}
and...
[Route("contact/conversations")]
public JsonResult ConversationWithContact(Guid? contactId)
{
... //this doesn't get hit
}
I keep getting this error:
I'm not sure how to properly bind the Guid such that it is received by the ASP.NET Controller.
Any ideas?? Much appreciated and have a great day!
Change your route to this:
[Route("~/contact/conversations/{id}")]
public JsonResult ConversationWithContact(string id)
{
if(!string.IsNullOrEmpty(id)){
var contactId= new Guid (id);
... //this doesn't get hit
}
}
and your ajax:
function getChat( contact_id ) {
$.get("/contact/conversations/"+contact_id)
.done( function(resp) {
let chat_data = resp.data || [];
loadChat( chat_data );
});
}
but if you use very old MVC and attribute routing doesnt work for you, try this:
function getChat( contact_id ) {
$.get("/contact/ConversationWithContact/"+contact_id)
.done( function(resp) {
let chat_data = resp.data || [];
loadChat( chat_data );
});
}

Angular promise return "undefined" value .NET MVC

In the following sample of code I send a "request" and I am trying to get a response but that returns "undefined" value.
This is my code so far
$scope.SameNameFunction = function() {
var payload = { itemname: $scope.EventDetails.Name};
portalRepository.namecall(payload).then(function (payload) {
console.log(payload.valuesreturned);
alert("Detected: " + payload.valuesreturned + " events having the same name");
});
};
Code from the http.post
namecall: function (payload) {
return $http.post("/Api/PortalData/NameNumberResult", payload);
},
Code from the .cs controller:
public ActionResult NameNumberResult(ItemEventNameDTO payload)
{
var valuetosend = payload.itemname;
var acf = new AcFunctions();
var newstorevalue = SqlHelper.ExecuteDataset(acf.AcConn(), "sp_selectbyname", valuetosend);
payload.valuesreturned = newstorevalue.Tables[0].Rows.Count;
return payload.GetSuccess();
}
Putting a breakpoint I am getting the appropriate value from the stored procedure, either in .cs and .js files. But while trying to print the message in screen, value do not appear and "Detected undefined events having the same name" is showing instead.
Any help is welcome!
As you per your code, you are returning promise
namecall: function (payload) {
return $http.post(url, payload);
}
You need to use the callback method of $http.post()
portalRepository.namecall(payload).then(function(data){
alert("Detected: " + payload.valuesreturned + " events having the same name");
});

.net mvc 4 application - call from ajax to a function in controller

I'm creating mvc 4 application where I call a function in controller from a js file using ajax.
When I call the function from ajax, its calling the respective function properly. But neither success nor error function is not firing . Could someone help me out to correct my mistake?
I would like to read the data from database convert it to json format and write it into a .js file and thereafter success function to be fired off. Help me to solve this. Thanks in advance.
Here is my Code.
$.ajax({
//url: '#Url.Action("getJsonData","Home")',
url: "Home/getJsonHugeData1",
//data: "{}",
type: "GET",
//contentType: 'application/json',
//dataType: "json",
success: function () {
alert();
alert('success getJsonHugeData');
loaddata(data);
},
error:function(){
alert('error');
}
});
Controller:
public JsonResult getJsonHugeData()
{
var users = GetUsersHugeData();
string json = "var dataSource=";
json += JsonConvert.SerializeObject(users.ToArray());
System.IO.File.WriteAllText(Server.MapPath("/Scripts/NewData.js"), json);
return Json(users, JsonRequestBehavior.AllowGet);
}
private List<UserModel> GetUsersHugeData()
{
var usersList = new List<UserModel>();
UserModel user;
List<dummyData> data = new List<dummyData>();
using (Database1Entities dataEntity = new Database1Entities())
{
data = dataEntity.dummyDatas.ToList();
}
for (int i = 0; i < data.Count; i++)
{
user = new UserModel
{
ID = data[i].Id,
ProductName = data[i].ProductName,
Revenue = data[i].Revenue,
InYear = data[i].InYear.Year
};
usersList.Add(user);
}
}
I believe your browser will block the file downloaded via ajax, this is because JavaScript cannot interact with disk. If you want to get this working, you will have to do so using a form post.
#using (Html.BeginForm("Action", "Controller", FormMethod.Post, new { id = "DownloadForm" }))
{
... form data would be here if you had any...
<button type="submit">Download</button>
}
You would then return a FileStreamResult with the contents of the file to be downloaded.
public ActionResult Action(FormModel model)
{
// Do work to get data for file and then return your file result to the browser.
return new FileStreamResult(new MemoryStream(fileData), "text/csv") // set the document type that is valid for your file
{
FileDownloadName = "users.csv"
};
}
I ran all of your code except for the following since you didn't provide the UserModel and dummydata classes in your question:
private List<UserModel> GetUsersHugeData()
{
var usersList = new List<UserModel>();
UserModel user;
List<dummyData> data = new List<dummyData>();
using (Database1Entities dataEntity = new Database1Entities())
{
data = dataEntity.dummyDatas.ToList();
}
for (int i = 0; i < data.Count; i++)
{
user = new UserModel
{
ID = data[i].Id,
ProductName = data[i].ProductName,
Revenue = data[i].Revenue,
InYear = data[i].InYear.Year
};
usersList.Add(user);
}
}
The end result was that you had a typo in your ajax 'url' parameter. Also, if you are going to check for errors, set your function to
function(jqxhr, status, error) {
alert(error);
}
to check the error being thrown.

Get return value from Controller to javascript

What I want is, I want to check whether there is a file in the database or not. To do this I have a method in the controller which checks this and returns a boolean for the corresponding case. It looks like this:
public bool fileInDb(int empId)
{
using (SLADbContext db = new SLADbContext())
{
bool file = db.CompetenceUploads.Any(x => x.EmployeeId == empId);
if (file)
{
return true;
}
else
{
return false;
}
}
}
I simply just check if there is any file assigned to the given employee.
Now I would like to call this method from my javascript in the view, and get the return value, so that I can let the user know, if there is a file assigned to the selected employee or not. It may look like this:
$("#get-file").click(function() {
empId: $("#EmployeeSelect").val();
var fileInDb = // Get the return value from the method 'fileInDb'
if(fileInDb) {
// Let the user download the file he/she requested
var url = "#Url.Action("GetUploadedFile", "Competence")";
this.href = url + '?empId=' + encodeURIComponent($("#EmployeeSelect").val());
} else {
alert("There is no file assigned to this employee.");
}
});
So my question now is, how do I get the get the return value from the method in the controller?
I would suggest few changes here:
Change your controller method to have return type ActionResult or JsonResult and I prefer JsonResult would be enough here and retrun Json response from controller and manipulate this method with $.get. You also need to change parameter to string because the parameter will be received as Json string.
public JsonResult fileInDb(string eId) //change signature to string and then convert to int
{
int empId=Convert.ToInt32(eId);
using (SLADbContext db = new SLADbContext())
{
bool file = db.CompetenceUploads.Any(x => x.EmployeeId == empId);
if (file)
{
return Json(new { result = true },JsonRequestBehavior.AllowGet);
}
else
{
return Json(new { result = false},JsonRequestBehavior.AllowGet);
}
}
}
Now your ajax-get call would be as below:
$("#get-file").click(function() {
var eId= $("#EmployeeSelect").val();
$.get('/YourControllerName/fileInDb',{'eId':eId},function(response){
//you just need to get the response so $.get is enough to manipulate
//this will be called once you get the response from controller, typically a callback
if(response.result) //same result variable we are returning from controller.
{
// Let the user download the file he/she requested
var url = "#Url.Action("GetUploadedFile", "Competence")";
this.href = url + '?empId=' + encodeURIComponent($("#EmployeeSelect").val());
} else {
alert("There is no file assigned to this employee.");
}
})
});
You need to set-up a single page script using your ASP fileInDb function and then communicate with that page using AJAX from the browser. If you're unfamiliar with AJAX I'd recommend using the jQuery implementation to get you started.
You can use jquery and ajax to achieve this. Call your method using an ajax call from your client code. Here is an example as a reference :Calling controller method from view
In the backend create a method to call, returning a JsonResult
public JsonResult fileInDb(int empId)
{
// your code - set fileExists to true/false
JsonResult returnObj = new JsonResult
{
Data = new
{
FileExists = fileExists ;
}
};
return Json(returnObj);
}
in your javascript code use $.ajax
$.ajax({
cache: false,
url: '#Url.Action("fileInDb")',
data: { 'empId': someVar },
type: 'POST',
success: function (response) {
if (response.Data.FileExists === true) {
// do something
} else {
// it was false
}
},
error: function (er) {
alert('Error!' + er);
}
});

using java script and JQuery to show message instead of throwing exception

How to show message(to inform user if group is added successfully or not) using Javascript and JQuery instead of throwing an erro. Actually this code check if group name already exist in database.
Controller :
[HttpPost]
public int CreateGroup(UserGroup group)
{
return bc.Create(group, user.id);
}
User group class:
UserGroupDalc Dalc = new UserGroupDalc();
public int Create(UserGroup group, int creatorId)
{
if(ByName(group.name) != null) throw new ArgumentException(string.Format("Group name: {0} is already exist.", group.name));
return Dalc.CreateGroup(group, creatorId);
}
User group dalc class:
public int CreateGroup(UserGroup group, int creatorId) {
connection();
com = new SqlCommand("spp_adm_user_group_ins", conn);
com.CommandType = CommandType.StoredProcedure;
com.Parameters.AddWithValue("#name", group.name);
com.Parameters.AddWithValue("#userid", group.creator_id);
conn.Open();
int i = com.ExecuteNonQuery();
if (i >= 1)
{
return 1;
}
else
{
return 0;
}
This js for posting data:
save: function () {
var jForm = $("#form1");
Metronic.blockUI();
GroupAPI.create(jForm.serialize(),
function (data) {
console.log(data);
},
function (error) {
console.log(error);
},
function () { Metronic.unblockUI(); });
}
}
}();
var GroupAPI = function () {
var url_create = "api/usergroup/createGroup";
var url_list = "api/usergroup/list";
return {
create: function (item, done, fail, always) {
var jqxhr = $.post(url_create, item);
jqXhrHandler(jqxhr, done, fail, always);
}
}
}();
Change user group class
UserGroupDalc Dalc = new UserGroupDalc();
public int Create(UserGroup group, int creatorId)
{
if(ByName(group.name) != null){
return 1;
}
return Dalc.CreateGroup(group, creatorId);
}
js
save: function () {
var jForm = $("#form1");
Metronic.blockUI();
GroupAPI.create(jForm.serialize(),
function (data) {
//console.log(data);
if (data == 0)
{
alert('added');
}else if(data == 1){
alert('already exist');
}
},
function (error) {
console.log(error);
},
function () { Metronic.unblockUI(); });
}
}
}();
it will be better to response a 422 status code, in this case indicate validation failed and server is not able to process the request, you can as well put the user readable message in the response response body
The 422 (Unprocessable Entity) status code means the server understands the content type of the request entity (hence a 415(Unsupported Media Type) status code is inappropriate), and the syntax of the request entity is correct (thus a 400 (Bad Request) status code is inappropriate) but was unable to process the contained instructions. For example, this error condition may occur if an XML request body contains well-formed (i.e., syntactically correct), but semantically erroneous, XML instructions.

Categories