WCF and Json Call - javascript

I am developing a WCF application and frontend uses JSON to call web methods.
I have a data model class as below
[DataContract]
public class GL_AccMainTypeListItem
{
[DataMember]
public int accMainTypeyNo { get; set; }
[DataMember]
public string mainType { get; set; }
[DataMember]
public int startAccNo { get; set; }
[DataMember]
public int endAccNo { get; set; }
}
My web method as below and return list of above objects. (These work well)
[OperationContract]
[WebInvoke(Method = "GET", UriTemplate = "GetDataString/{value}", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
public List<GL_AccMainTypeListItem> GL_AccMainType_GetAll()
{
DataAccessService da = new DataAccessService("usp_GL_AccMainTypeGetAll");
DataTable dt = da.ExecuteDataTable();
var acc = (from row in dt.AsEnumerable()
select new GL_AccMainTypeListItem
{
accMainTypeyNo = Utility.ToInt(row["accMainTypeNo"]),
mainType = Utility.ToString(row["mainType"]),
startAccNo = Utility.ToInt(row["startAccNo"]),
endAccNo = Utility.ToInt(row["endAccNo"])
});
return acc.ToList();
}
Basically here I used stored procedure and get a data table from database and return to client. I want to know how can I call this web service in client side using JQuery and iterate results set row by row.

<script src="jquery-1.11.2.js"></script>
<script>
$(document).ready(function () {
$('#btnGetAccountList').click(function () {
$.ajax({
//url will be yourclassname.svc/yourmethodname
url: 'namespaceofGL_AccMainType_GetAllmethod.svc/GL_AccMainType_GetAll',
method: 'Get',
contentType: "application/json;charset=utf-8",
success: function (data) {
//your account detail list will be here.
},
error: function (err) {
alert(err);
}
});
});
});
</script>

You have to make a ajax call to that method.
Eg:
// Function to call WCF Service
function CallService() {
$.ajax({
type: Type, //GET or POST or PUT or DELETE verb
url: Url, // Location of the service
data: Data, //Data sent to server
contentType: ContentType, // content type sent to server
dataType: DataType, //Expected data format from server
processdata: ProcessData, //True or False
success: function(msg) {//On Successfull service call
ServiceSucceeded(msg);
},
error: ServiceFailed// When Service call fails
});
}

Related

ASP Net Core3.1 AJAX Post Sending NULL to Controller

It has been 3 days am trying to sending the [POST] form data using ajax, Javascript & HTML into MVC controller but getting null.
Please find the controller and ajax code please help me on this also let me know is it possible or not to send the data from ajax to mvc controller?
I am beginner .....thanks in advance.
[HttpPost]
[AllowAnonymous]
public async Task<IActionResult> CreateNewBug([FromBody] BugTrackerRequest bugTrackerRequest)
{
// BugTrackerResponse bugTrackerResponse = null;
if (ModelState.IsValid)
{
var Request = await _projectDetails.CreateNewBug(bugTrackerRequest);
if (Request > 0)
{
BugTrackerResponse bugTrackerResponse = new BugTrackerResponse();
bugTrackerResponse.Issuccess = true;
// return Ok(new {Messgage="Data save successfully in the DB"});
return Ok();
}
}
return StatusCode(500, new { Message = "Something went wrong" });
// return bugTrackerResponse;
//return StatusCode();
}
public class BugTrackerRequest:APIResponse
{
public int TicketId { get; set; }
public string ProjectName { get; set; }
public string ProjectDescription { get; set; }
public string Title { get; set; }
public string Status { get; set; }
public string AssignTo { get; set; }
public string AssignFrom { get; set; }
public byte[] Attachment { get; set; }
public string Impact { get; set; }
public string Platform { get; set; }
public string Priority { get; set; }
public string BugType { get; set; }
public DateTime CreatedDate { get; set; }
}
}
function savedetails() {
let saveuidetails = new BugdetailRequestclass();
saveuidetails.ProjectName = $('#projectprojectname').val();
saveuidetails.ProjectDescription = $('#description').val();
saveuidetails.Title = $('#title').val();
saveuidetails.Status = $('#status').val();
saveuidetails.AssignTo = $('#assignto').val();
saveuidetails.AssignFrom = $('#assignfrom').val();
saveuidetails.Attachment = $('#Attfileupload').val;
saveuidetails.Impact = $('#Priority').val();
saveuidetails.Platform = $('#platform').val();
saveuidetails.Priority = $('#Priority').val();
saveuidetails.BugType = $('bugtype').val();
saveuidetails.CreatedDate = $('#currentdate').val();
$.ajax({
type: 'POST',
url: '/TicketController1/CreateNewBugFromBody',
dataType: "json",
contentType: 'application/json',
data: JSON.stringify(saveuidetails),
success: function (data) {
console.log('success', data);
},
error: function () { alert('Exeption:'); }
});
}
Your URL in POST is wrong, please change
/TicketController1/CreateNewBugFromBody
to
/TicketController1/CreateNewBug
Please verify that your controller class is named TicketController1.
To start with, please comment out
saveuidetails.Attachment = $('#Attfileupload').val;
in js and
public DateTime CreatedDate { get; set; }
public byte[] Attachment { get; set; }
When controller method is working, you may look at the Attachment which will be a challenge.
You basically have three choices (https://stackoverflow.com/a/4083908/14072498):
Base64 encode the file, at the expense of increasing the data size by
around 33%, and add processing overhead in both the server and the client
for encoding/decoding.
Send the file first in a multipart/form-data POST, and return an ID to the
client. The client then sends the metadata with the ID, and the server re-
associates the file and the metadata.
Send the metadata first, and return an ID to the client. The
client then sends the file with the ID, and the server re-associates the
file and the metadata.
Else, your code shown here looks OK to me, and there is no problem using a MVC controller for this. If controller contains API methods only, you should extend from ControllerBase instead of Controller, and annotate controller with [ApiController]. The latter invokes model validation automatically.
When implementing new API end-points, always start with something simple and verify with e.g. Postman that you can reach your new end-point.
url: '/TicketController1/CreateNewBugFromBody',
public async Task<IActionResult> CreateNewBug([FromBody] BugTrackerRequest bugTrackerRequest)
First, check your request URL and the action method, it seems that you are submitting the form to the CreateNewBugFromBody method, instead of CreateNewBug action method. So try to change your code as below (I assume your controller name is TicketController1 and you want to submit to the CreateNewBug method):
$.ajax({
type: 'POST',
url: '/TicketController1/CreateNewBug',
dataType: "json",
contentType: 'application/json',
data: JSON.stringify(saveuidetails),
success: function (data) {
console.log('success', data);
},
error: function () { alert('Exeption:'); }
});
Second, please check your JQuery object BugdetailRequestclass, in the action method, it receives a BugTrackerRequest object. So, try to modify your code as below (please change the request url and the jquery selector value to yours):
function savedetails() {
var saveuidetails = {}; //define a object
saveuidetails.ProjectName = $('#ProjectName').val();
saveuidetails.ProjectDescription = $('#Description').val();
saveuidetails.Title = $('#Title').val();
saveuidetails.Status = $('#Status').val();
saveuidetails.AssignTo = $('#AssignTo').val();
saveuidetails.AssignFrom = $('#AssignFrom').val();
saveuidetails.Attachment = $('#Attfileupload').val;
saveuidetails.Impact = $('#Priority').val();
saveuidetails.Platform = $('#Platform').val();
saveuidetails.Priority = $('#Priority').val();
saveuidetails.BugType = $('#BugType').val();
saveuidetails.CreatedDate = $('#CreatedDate').val();
$.ajax({
type: 'POST',
url: '/Home/CreateNewBug',
dataType: "json",
contentType: 'application/json',
data: JSON.stringify(saveuidetails),
success: function (data) {
console.log('success', data);
},
error: function () { alert('Exeption:'); }
});
}
Besides, you could add a breakpoint in the JavaScript resource and CreateNewBug action method, and check whether you could get the correct data before/after send Ajax request.
Screenshot as below:
JavaScript debug screenshot (using F12 developer tools)
Action method debug screenshot:

Passing objects from Ajax to C# WebApi

I’m still not fluent in calling WebAPI services. I succeed in simple items, but now my needs are getting complicated and things always fail.
I use MVC 5 for WebAPI, and call using regular jQuery functions.
My Model
Here I manage appointments of patients in a clinic. I use the following model for Patient and Appointment entities:
public class Patient
{
// Personal data
public int Id { get; set; }
public string Name { get; set; }
}
public class Appointment
{
public int Id { get; set; }
public DateTime Date { get; set; } // date only
public int Order { get; set; }
public string PatientName { get; set; }
// Parent data
public Patient Patient { get; set; }
public int PatientId { get; set; }
public Organization Organization { get; set; }
public int OrganizationId { get; set; }
}
My DTOs
public class AppointmentDto
{
public int Id { get; set; }
public int Order { get; set; }
public string PatientName { get; set; }
public PatientDto Patient { get; set; }
}
public class PatientDto
{
public string Name { get; set; }
}
First Case
I want to set new ordering for appointments within a day. I send list of JSON objects with IDs of appointments to be changed and their respective orders.
The service action:
[HttpPost]
public IHttpActionResult UpdateOrder(List<AppointmentDto> dto)
{
_unitOfWork.Appointments.UpdateOrder(dto);
_unitOfWork.Complete();
return Ok();
}
The service call:
// Handler methods
var rearrangeAppointments = function (event, ui) {
// Json object to pass
var orderedAppointments = [];
// Looping through appointments
var i = 0;
$("#sortable").children().each(function () {
// Set new order
i++;
orderedAppointments.push({ "Id": this.getAttribute("data-id").toString(), "Order": i.toString() });
});
// Call service
appointmentsService.updateOrder(orderedAppointments, done, fail);
};
var updateOrder = function (orderedAppointmens, done, fail) {
$.ajax({
url: "/api/appointments",
method: "POST",
data: orderedAppointmens,
dataType: "Json"
})
.done(done)
.fail(fail);
};
The service is called successfully, but the passed list is always empty. I debugged the JavaScript code and the array of JSON object is built successfully. Also debugged the MVC code and tested the service Postman, it works very fine. This drop is passing the list of objects from client to server.
Second Case
This time it’s a get call. I want to get list if appointments if a specific date to update the view.
The service action:
public IEnumerable<AppointmentDto> GetAppointments(DateTime date)
{
var organizationId = _unitOfWork.ApplicationUsers.GetOrganizationId(User.Identity.GetUserId());
var appointments = _unitOfWork.Appointments.GetAppointments(date, organizationId);
return appointments.Select(Mapper.Map<Appointment, AppointmentDto>);
}
The service call:
$("#datepicker").datepicker({
// TODO: Refactor to pettern
onSelect: function (dateText, inst) {
var selectedDate = $(this).datepicker('getDate');
var date = JSON.stringify(selectedDate);
$.ajax({
contentType: 'application/json; charset=utf-8',
dataType: "json",
url: "/api/appointments",
data: date,
success: function (appointments) {
alert("Service call succeeded!")
alert(appointments.length);
}
})
.fail(function () {
alert("Failure!");
});
}
});
When I test the code without passing a date (hardcoding the date into the action method) it works very well. When I add the date to the parameters (in the action method and the AJAX call), it does not work at all.
I've tried many links and articles from here and other sources with no success, like below:
Pass a datetime from javascript to c# (Controller)
Pass Date Values from Ajax Call to MVC
and more that I could not add here.
I think my major problem in the two cases in passing data.
What am I missing here?
for the second case : Do you sent date-time ?? if you do that the URL may contains ":" (12:00) & this type of character is denied by the HTTP request
After some tracing with one friend, and reviewing some other articles and questions...
First Case (passing list of objects)
I reformatted the array of objects using JSON.stringify(orderedAppointmens), and added contentType: 'application/json; charset=utf-8' to the service call. The code should look like below:
var updateOrder = function (orderedAppointmens, done, fail) {
orderedAppointmens = JSON.stringify(orderedAppointmens);
$.ajax({
url: "/api/appointments",
method: "POST",
data: orderedAppointmens,
contentType: 'application/json; charset=utf-8',
dataType: "Json"
})
.done(done)
.fail(fail);
};
Second Case (passing a Date object)
I removed the Json dataType from the service call and concatenated the date to the URL like below:
$.ajax({
url: "/api/appointments?date=" + selectedDate.toISOString(),
type: "GET",
success: function (appointments) {
alert(appointments.length);
}
});
This worked fine and the Date object is passed to the DateTime object in backend successfully.

Send Multiple objects with Ajax to the ASP.NET MVC controller

I have one ViewModel that contains three Collection of ExternalProjectViewModel, CertificateUniverSityViewModel, CertificateInstitutionsViewModel.
CreateFreelancerProfileViewModel.cs
public class CreateFreelancerProfileViewModel : BaseViewModel
{
// More ...
public List<ExternalProjectViewModel> ExternalProjects { get; set; }
public List<CertificateUniverSityViewModel> CertificateUniverSitys { get; set; }
public List<CertificateInstitutionsViewModel> CertificateInstitutions { get; set; }
}
My Ajax code:
$('#Controller').on('click','#SaveProfile',
function() {
debugger;
var CertificateInstitutions =
JSON.parse(localStorage.getItem("CertificateInstitutionsListLocal"));
var CertificateUniverSitys =
JSON.parse(localStorage.getItem("CertificateUniverSitysListLocal"));
var ExternalProjects =
JSON.parse(localStorage.getItem("ExProjectListLocal"));
$.ajax({
url : '#Url.Action(MVC.Freelancer.Profile.CreatePrfile())',
method: "POST",
data: {
ExternalProjects,
CertificateUniverSitys,
CertificateInstitutions
}
});
});
When I Want Send Objects to Controller, First Get It from LocalStorage
And After Get it Send it to Controller Action:
public virtual ActionResult CreatePrfile(CreateFreelancerProfileViewModel viewModel)
When I see viewModel Values Show My Objects Count That is 2 but Objects Properties is null.so that my server object properties name equally with the client Object properties name.
LocalStorage Values
[{"ExternalProjects":{"Name":"wqeqwe","Body":"wqewqe","Url":‌​"wqewqe"}}]
[{"CertificateUniverSity":{"Name":"sad","Description":"sadas‌​","DateOfGets":"sad"‌​,"CertificateType":"‌​2","Field":"sadasd",‌​"UniName":"sad","Cer‌​tificateUniverSityLe‌​vel":"2"}}]
You could send them as JSON payload:
$.ajax({
url : '#Url.Action(MVC.Freelancer.Profile.CreatePrfile())',
method: 'POST',
contentType: 'application/json',
data: JSON.stringify({
externalProjects: ExternalProjects,
certificateUniverSitys: CertificateUniverSitys,
certificateInstitutions: CertificateInstitutions
}),
success: function(result) {
alert('data sent successfully');
}
});
This assumes that the instances you got from the localStorage of those 3 variables represent javascript arrays with the corresponding objects in it.

ajax post on MVC .NET does not pass array correctly

I have a simple modal that uses select2 to get a list of Products from the server. User can multiple choose products and hit Ok to refine a search.
My following setup grabs the data from the modal and does an ajax call against a Controller action with a strongly typed view model that matches what the JS is trying to send via the ajax call.
Ajax:
var exploreFilters = {
"type" : exploreType,
"products" : $('#s2id_select2-products').select2('data'),
"locations" : $("#page-report__data").data("criteria__locations"),
"companies" : $("#page-report__data").data("criteria__companies"),
"usertypes" : $("#page-report__data").data("criteria__usertypes"),
"groupusers" : $("#page-report__data").data("criteria__groupusers"),
"datestart" : $("#page-report__data").data("criteria__datestart"),
"dateend" : $("#page-report__data").data("criteria__dateend")
};
$.ajax({
dataType: "html",
type: "POST",
url: "/Report/Group/FilteredView",
data: exploreFilters,
success: function(html) {
if($.trim(html) === "")
$targetSection.html('<div class="page-report__empty">No data found. Please adjust your search filters and try again.</div>');
else
$targetSection.html(html);
},
error: function(xhr, text, err) {
if(text === "timeout")
$targetSection.html('<div class="page-report__empty">The request timed out. Please try again.</div>');
else
$targetSection.html('<div class="page-report__empty">There has been an error.</div>');
}
});
Right before the ajax call goes to the controller I inspect the content and structure of exploreFilters:
Here is how the form data looks on the POST request:
On the other side I got a controller which takes a strongly-typed parameter with a structure similar to what exploreFilters has:
public ActionResult FilteredView(ReportCriteriaViewModel criteria)
{
throw new NotImplementedException();
}
And my strongly-typed view model:
public class ReportCriteriaViewModel
{
public ProductViewModel[] Products { get; set; }
public string[] Locations { get; set; }
public string[] Companies { get; set; }
public string UserTypes { get; set; }
public string GroupUsers { get; set; }
public string DateStart { get; set; }
public string DateEnd { get; set; }
}
public class ProductViewModel
{
public Guid Id { get; set; }
public string Text { get; set; }
}
Once the controller action gets hit I can see that DateStart and DateEnd have been successfully bound but not my list of products.
I cannot change the datatype on the json request, it has to be html because my controller action is going to be returning html.
I've tried changing the capitalization on Id and Text, JSON.stringify (which actually makes the dates not bind anymore)
What am I doing wrong?
Try to add contentType: "application/json" in your Ajax request
$.ajax({
...
contentType: "application/json",
...
});
The problem is in how you are serializing the list:
products[0][id]
products[0][text]
You need to send your list in this format:
products[0].id
products[0].text
id and text should be properties, without the [] otherwise it is treated as an index to a two-dimensional array.
You should try
contentType: "application/json; charset=utf-8"
in the options of the $.ajax call
$.ajax({
dataType: "html",
type: "POST",
url: "/Report/Group/FilteredView",
data: exploreFilters,
contentType: "application/json; charset=utf-8" ....

Modify the postData of jqGrid before call to AJAX-enabled WCF Service

I have an AJAX-enabled WCF service with the following signature:
[OperationContract]
[WebGet]
public JQGridContract GetJQGrid(int entityIndex)
And the following data contract:
[DataContract]
public class JQGridContract
{
[DataContract]
public class Row
{
[DataMember]
public int id { get; set; }
[DataMember]
public List<string> cell { get; set; }
public Row()
{
cell = new List<string>();
}
}
[DataMember]
public int page { get; set; }
[DataMember]
public int total { get; set; }
[DataMember]
public int records { get; set; }
[DataMember]
public List<Row> rows { get; set; }
public JQGridContract()
{
rows = new List<Row>();
}
}
Basically I need to change the postData of the client-side jqGrid to send 'entityIndex' to this service.
I've read how its supposed to function and from what I can tell this should work:
function loadGrid() {
$("#jqGrid").jqGrid({
postData: { entityIndex : function () { // modify the data posted to AJAX call here
return 6;
})
},
gridComplete: function () {
$("#jqGrid").setGridParam({ datatype: 'local' });
},
datatype: function (pdata) {
getData(pdata);
},
And here is the getData() function:
function getData(pdata) {
var params = new Object();
alert(pdata.entityIndex()); // this displays '6', correctly
params.entityIndex = pdata.entityIndex();
$.ajax(
{
type: "GET",
contentType: "application/json; charset=utf-8",
url: "AJAXService.svc/GetJQGrid",
data: JSON.stringify(params),
dataType: "json",
success: function (data, textStatus) {
if (textStatus == "success") {
var thegrid = $("#jqGrid")[0];
thegrid.addJSONData(data.d);
}
},
error: function (data, textStatus) {
alert('An error has occured retrieving data!');
}
});
Ive confirmed the following in Firebug:
1) The json params are correct : {"entityIndex":6}
2) The AJAX service returns JSON data to the grid, its just the wrong data
And here is the wierd part:
I logged the 'entityIndex' thats actually working inside the WCF operation -- and its ALWAYS coming up as 0?
Thanks.
I will not criticize the style of your program. I could write too many things about this. :-)
You current main problem could be solved with the usage JSON.stringify(pdata.entityIndex()) instead of JSON.stringify(params) or with the usage of another BodyStyle of the WFC method (see here for details)
I got it working, it is close to what Oleg said, just that you do not need to do JSON.stringify.
If you have WebMessageBodyStyle.WrappedRequest, this works:
data: { entityIndex: pdata.entityIndex() },
OR if you have no BodyStyle, this works:
data: { "entityIndex": pdata.entityIndex() },

Categories

Resources