Not able to bind data to datatable in ASP.NET MVC - c#

Below is my code from view from my ASP.NET MVC project. I am using datatable to create a table. I am fetching data from a Web API. Data is being returned but while binding I get the error shown here. I tried deleting a lot of code which had buttons. Now I just have code for simply binding it.
datatables warning: table id=patients - ajax error. for more information about this error, please see http://datatables.net/tn/7
jQuery code :
$(document).ready(function () {
debugger;
var table = $("#patients").DataTable({
ajax: {
url: "/api/patients",
dataSrc: ""
},
columns: [
{
data: "First_Name"
},
{
data: "phoneNumber",
render: function (data) {
debugger;
return data.toString().replace(
/(\d\d\d)(\d\d\d)(\d\d\d\d)/g, '$1-$2-$3');
}
},
{
data: "Address"
},
]
});
});
API code from controller:
public IHttpActionResult GetPatients()
{
var patientDto = getdata();
return Ok(patientDto);
}
public IEnumerable<Patient_Response> getdata()
{
IEnumerable<Patient_Response> students = null;
using (var client = new HttpClient())
{
client.DefaultRequestHeaders.Add("Authorization", "Bearer 0f6af107-6ad2-4665-ad24-f09402d50082");
client.BaseAddress = new Uri("http://localhost:6600/api/");
// HTTP GET
var responseTask = client.GetAsync("patients");
responseTask.Wait();
var result = responseTask.Result;
if (result.IsSuccessStatusCode)
{
var readTask = result.Content.ReadAsAsync<IList<Patient_Response>>();
readTask.Wait();
students = readTask.Result;
}
else //web api sent error response
{
// log response status here..
students = Enumerable.Empty<Patient_Response>();
ModelState.AddModelError(string.Empty, "Server error. Please contact administrator.");
}
}
return students;
}
What is wrong? I am not able to figure out.

Did you read the documentation: https://datatables.net/manual/tech-notes/7
This occurs when jQuery falls into its error callback handler (this callback built into DataTables), which will typically occur when the server responds with anything other than a 2xx HTTP status code.
That means that your call go the controller, failed to bring any data.
You can use the following code to see what went wrong:
$.fn.dataTable.ext.errMode = 'none';
$('#patients')
.on( 'error.dt', function ( e, settings, techNote, message ) {
alert( 'An error has been reported by DataTables: ', message );
} )
.DataTable();

Related

Ajax method calling a Web Api who its consuming a gRPC Service (how to get a list from a db?): Errors 415 and 400

I have problems in my web console, first it gives me error 415 without contentType: 'application/json; charset=UTF-8', in ajax method and with it gives me error 400.
I also try doing debug if the error is in backend code but it never happens and it jumps off (this don't make any sense, the debugger should run...)
My goal is to return a list of users and their email, something like this
//trying to do this in my service
IEnumerable()
//class c#
ShowUsers:
(string)Username: User1
(string)Email:user1#example.com
But I'm doing this in gRPC, so I'll have a web API controller calling the gRPC method
As there is no IEnumerable in gRPC, so my proto and method look like this:
Proto:
syntax = "proto3";
option csharp_namespace = "GrpcService1.Protos";
package UserAuth;
service UserAuth {
rpc GetAllUsers(MessageRequest) returns(ListUsersResponse);
}
message ListUserResponse{
string username = 1;
string email = 2;
}
message ListUsersResponse{
repeated ListUserResponse lstUsers = 1;
}
message MessageRequest{
string message = 1;
}
gRPC method service c#
public override Task<ListUsersResponse> GetAllUsers(MessageRequest request, ServerCallContext context)
{
//This gives me an IEnumerable<ShowUsers> (this is
correct)
var a = _userBll.getAllUsers();
//Here in this lines maybe be the problem but I don't
//know where (maybe be because of json type or something into a list)
//here im trying to put separate list of users and emails
var names = a.Select(x => x.Username);
var emails = a.Select(y => y.Email);
//here im trying to put the lists into a Response
var all = new ListUserResponse
{
Username = names.ToString(),
Email = emails.ToString()
};
//the above will give the same but the
ListUsersResponse is a repeated attribute
var response = new ListUsersResponse
{
LstUsers = { all }
};
//all ok
request.Message = "Sucess";
return Task.FromResult(response);
}
The code below is correct (I test with a POST method the controller and the ajax I test without the gRPC and works fine) but you will have the idea of ​​what I'm doing (its the controller and the ajax method)
Controller [HTTPGET]:
[HttpGet("getAllUserInfo_2"), Authorize]
public async Task<ActionResult<ListUsersResponse>> GetAll_2([FromBody] MessageRequest message)
{
_logger.Log(LogLevel.Information, "Request Received for AuthController::Register");
var results = await _userClient.GetAllUsersAsync(message);
_logger.Log(LogLevel.Information, "Sending Response from AuthController::Register");
return Ok(results);
}
Ajax Method:
$(function b() {
debugger;
var $users_A = $('#users_A');
$.ajax({
contentType: 'application/json; charset=UTF-8', //if I comment this gives me 415
url: uri_3_2,
type: 'GET',
dataType: 'json',
beforeSend: function(request) {
request.setRequestHeader("Authorization", 'Bearer ' + localStorage.getItem("key"));
},
success: function(date) {
$.each(data, function (i, rice) {
$users_A.append('<li>Name: ' + arroz.username + ' Email: ' + arroz.email + ' </li>');
});
},
error: function (xhr, textStatus, errorThrown) {
console.log('XHR:' + xhr + '\nTextStatus:' + textStatus + '\nErrorThrown:' + errorThrown); //this should give me more info about the error but don't works... But it
//works fine the implementation code
$users_A.append('<h4>ERRRROORRRR</h4>');
}
});
});
Any help is welcome
A bi-directional streaming RPC would be a better option as it will
improve your performance significantly and may solve your problem.
you need to change your proto as the following:
syntax = "proto3";
option csharp_namespace = "GrpcService1.Protos";
package UserAuth;
service UserAuth {
rpc GetAllUsers(MessageRequest) returns(stream UserResponse);
}
message UserResponse{
string username = 1;
string email = 2;
}
message MessageRequest{
string message = 1;
}
gRPC method service c#
public override async Task GetAllUsers(MessageRequest request, IServerStreamWriter<UserResponse> responseStream, ServerCallContext context)
{
var users = _userBll.getAllUsers();
foreach (user in users)
{
await responseStream.WriteAsync(new UserResponse
{
Username = user.Username.ToString(),
Email = user.Email.ToString()
});
}
}
in client:
public async Task<List<UserResponse> GetAllUsers()
{
var userResponseList = new List<UserResponse>();
using var call = client.GetAllUsers(new MessageRequest());
while (await call.ResponseStream.MoveNext())
{
var userResponse = new UserResponse
{
Username = call.ResponseStream.Current.Username,
Email = call.ResponseStream.Current.Email
});
userResponseList.Add(userResponse);
}
return userResponseList;
}
the client object has come from the channel which is created from the gRPC service URL (I assume you know it).
Now you can make this a service and call it by dependency injection from your controller.
I didn't test it so it may have some compile errors but the approach is correct.

Image Uploading using angular and asp.net

am trying to get the image from the PC and upload it into the DB
as like "/Images/aaa.jpg" am new to angular. Here am tried one example. Its not worked For me. i have stucked almost 3 days to solve this. but i couldn't found any tutorials for my requirement. when i debug the id, and descriptions are passing correctly, but For the path its remaining always null. and i know i need to set path to where the picture will save. but i dont know how to do that, please can anyone help me to solve this issue.
I tried this one to upload image.
$scope.uploadFile = function(files) {
var fd = new FormData();
//Take the first selected file
fd.append("file", files[0]);
$http.post(uploadUrl, fd, {
withCredentials: true,
headers: {'Content-Type': undefined },
transformRequest: angular.identity
}).success(ya).error( noo );
};
There is a add button if user hit add button details want to be save. for this i used this one.
$scope.AddImage = function () {
var dataObj = {
Id: $scope.Id,
Description: $scope.Description,
Path: $scope.Path,
Location: $scope.Location,
};.
var request = $http({
method: 'POST',
url: urls.api + 'Images/AddImage',
//data: JSON.stringify(dataObj)
data: dataObj
}).success(function (data, status) {
alert('saved succesfully');
})
.error(function (error) {
$scope.status = 'Unable to load ImageDetails : ' + error.message;
console.log($scope.status);
});
}
this is my asp.net services.
public async Task<int?> Addimg (Addimg dto)
{
try
{
var d = _dbContext.img
.FirstOrDefault();
d.img_Path = dto.Path.ToString();
d.img_Description = dto.Description;
d.img_Location = dto.Location;
//mark entry as modifed
_dbContext.Entry(d).State = EntityState.Modified;
await _dbContext.SaveChangesAsync();
return d.img_Id;
}
this my asp.net controller
[HttpPost]
[Route("AddImage")]
public async Task<IHttpActionResult> AddBanner(DisplayBannersDto dto)
{
if (!ModelState.IsValid)
return BadRequest(ModelState);
int? result = await _service.Addbanner(dto);
return Ok();
}
}
Please provide if there is any alternative codes.
It looks like you're uploading a file and doing nothing with it...
You could add something like the following property to your DisplayBannersDto model:
public Stream InputStream { get; set; }
You can then either save the file to disk from the stream, or in the database as a blob.

PayPal express checkout: checking payment can be performed on button click

I'm using PayPal express checkout (checkout.js V4.0.0) with asp.net mvc to allow a user to pay for data transactions. What I need to do when the express checkout button is clicked is perform some checks on the database and confirm that PayPal can proceed (this is also time related, as the database could be in a locked processing state).
I've setup the Advanced Server Integration and I then call the create-payment controller from the payment section in paypal.Button.render, but this expects a json object with a PaymentID element to be returned. At what point am I able to perform these checks on server side and abort from the paypal process if PayPal can't continue? If a check fails, the server side also needs to return an appropriate error page or message to be displayed.
This is the paypal button code:
<script src="https://www.paypalobjects.com/api/checkout.js"></script>
<script>
paypal.Button.render({
env: 'sandbox',
payment: function (resolve, reject) {
var CREATE_PAYMENT_URL = '#Url.Action("PayTransactions","Pending")';
paypal.request.post(CREATE_PAYMENT_URL)
.then(function (data) { resolve(data.paymentID); })
.catch(function (err) { reject(err); });
},
onAuthorize: function(data) {
var EXECUTE_PAYMENT_URL = 'https://my-store.com/paypal/execute-payment';
paypal.request.post(EXECUTE_PAYMENT_URL,
{
paymentID: data.paymentID,
payerID: data.payerID
})
.then(function(data) { /* Go to a success page */ })
.catch(function (err) { /* Go to an error page */ });
},
onCancel: function (data, actions) {
return actions.redirect();
},
onError: function (err) {
// Show an error page here, when an error occurs
}
}, '#paypal-button');
</script>
which at the payment section calls this:
public async Task<string> PayTransactions()
{
// check if payment is still necessary or end of month is running
var condition = await CheckDatabaseIsUsable();
switch (condition)
{
case 1:
ModelState.AddModelError("error", "some error message");
return RedirectToAction("Index", "Pending");
case 2:
ModelState.AddModelError("error", "some other error");
return RedirectToAction("Index", "Pending");
}
var paypalPayment = FormPayPalPaymentObject();
return JsonConvert.SerializeObject(new { paymentID = paypalPayment.PaymentId });
}
The problem is that I am now mixing the ActionResult and json string return types.
You can return json also for the redirection responses and control with javascript when it is a redirection or and ok response.
Server side:
return JsonConvert.SerializeObject(new { redirect= Url.Action("Index", "Pending") });
Javascript:
paypal.request.post(CREATE_PAYMENT_URL)
.then(function (data) {
if(data.redirect)
{
//cancel the flow and redirect if needed
window.location.href = data.redirect;
}else{
resolve(data.paymentID);
}
})
.catch(function (err) { reject(err); });
},
Using an IActionResult object as the return value for the PayTransactions is preferable
public async Task<IActionResult> PayTransactions()
{
...
return Json(new { paymentID = paypalPayment.PaymentId });
}
Also consider that the modelstate errors you are adding are useless because of the redirection.
You can call reject(error) to cancel the payment.

400 bad request on ASP.NET MVC controller

Was wondering if someone can see what I can't see. The site is giving me an error of "http://localhost:XXXXX/Sales/Edit/[insert ID here] responded with a status of 400 (Bad Request)"
Here's my controller:
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Edit([Bind(Include = "")] Sale sale)
{
// Retrieve Part Number
Product product = await RetrieveProductUsingPartNumber(filter["ProductPartNumber"]);
// Validate Part Number
if (ValidateProduct(product)) s.ProductId = product.Id;
if (ModelState.IsValid)
{
salesRepository.Update(s);
await salesRepository.SaveAsync();
return Json(new SaleDtoWeb()
{
ProductPartNumber = s.Product.PartNumber
});
}
// Set response to error
Response.StatusCode = 400;
// Retrieve error messages
List<string> errors = RetrieveErrorMessages();
return Json(new { messages = errors });
}
Here's my POST
updateItem: function (item) {
return $.ajax({
type: "POST",
url: "Sales/Edit/" + item.Id,
data: AddAntiForgeryToken(item),
dataType: "json",
success: function (data) {
// Show Success message
showAlert('.alert-success', 'Successfully edited item');
// Hide Error alert
$('.alert-danger').hide();
},
error: function (data) {
var messages = JSON.parse(data.responseText);
// Format messages from server
var errorMessages = formatErrorMessages(messages['messages']);
// Show Error messages
showAlert('.alert-danger', errorMessages);
// Hide Success alert
$('.alert-success').hide();
}
});
}
EDIT: I've added the parameters/method signature to the controller. Mind you I didn't add the binded items because I want to focus on the just the PartNumber which is on another model/table
try adding:
Response.TrySkipIisCustomErrors = true;
It looks like your ModelState isn't valid. What does the controller method signature look like? Does it match what AddAntiForgeryToken(item) is passing?
What does the error message array tell you?

Console Log Returning HTML Page Text Instead of JSON

I am trying to return a model in JSON form from a request sent as the following:
$(document).ready(function() {
(function(){
console.log("ran");
$.ajax({
type: "GET",
url: "https://clas.uconn.edu/Employees/Edit/22",
success: function(data) {
console.log("Success: " + data);
empData = data;
}
});
})();
});
My Controller for this method is:
// GET: Employees/Edit/5
public ActionResult Edit(int? id)
{
var id = employee.id;
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
if (employee == null)
{
return HttpNotFound();
}
return new JsonResult() { Data = employee, JsonRequestBehavior = JsonRequestBehavior.AllowGet };
Console.WriteLine("error");
}
However I am getting an entire html page in the consol log even though none of these controller actions return a view. Any ideas?
Edit:
After adding the datatype, I am getting an error in the console log saying:
GET http://localhost:59909/Employees/EmployeeLookupDisplay
net::ERR_CONNECTION_REFUSED
It is returning the entire page because there is an error in your request somewhere.
Add a block error to your ajax call and console.log on the xhr. You will get much more information about the error like this.
What you can try is making the request on POST and checking the properties of the context on the C# code. Sometimes adding dataType and the encoding helps for the request.
Additionally check for the returning status of your request on your browser developer tools. In chrome it is the network tab that shows all requests and their status.
Try This, but according to your code its always returning HTTP not foud which is HTML page. if you have data to employee. i mean your controller action getting success without any error. then you can try tis.
$.ajax({
type: "GET",
url: "https://clas.uconn.edu/Employees/Edit/22",
dataType: "json",
success: function(data) {
console.log("Success: " + data);
empData = data;
}
Maybe instead of returning new JsonResult() { Data = employee, JsonRequestBehavior = JsonRequestBehavior.AllowGet };, just return Json(employee, JsonRequestBehavior.AllowGet);'
Another thing i see:
on the first line you are doing var id = employee.id; -> where employee comes from? maybe the error is there.

Categories

Resources