简体   繁体   中英

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' 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM