1

I am sending data to a rest API of a travel portal. According to their documentation, the json data must be in the following format

{
    "EndUserIp": "192.168.10.10",
    "TokenId": "ac2751e9-4cc3-406f-b678-c947e4f57a00",
    "AdultCount": "1",
    "ChildCount": "0",
    "InfantCount": "0",
    "DirectFlight": "false",
    "OneStopFlight": "false",
    "JourneyType": "1",
    "PreferredAirlines": null,
    "Segments": [
    {
        "Origin": "DEL",
        "Destination": "BOM",
        "FlightCabinClass": "1",
        "PreferredDepartureTime": "2015-11-06T00: 00: 00",
        "PreferredArrivalTime": "2015-11-06T00: 00: 00"
    }],
    "Sources": [
        "6E"
    ]
}

My models are

public class otherType
{
    public string Origin { get; set; }
    public string Destination { get; set; }
    public FlightCabinClass FlightCabinClass { get; set; }
    [DisplayFormat(NullDisplayText = "", DataFormatString = "{0:yyyy-MM-dd}")]
    public DateTime? PreferredDepartureTime { get; set; }
    [DisplayFormat(NullDisplayText = "", DataFormatString = "{0:yyyy-MM-dd}")]
    public DateTime PreferredArrivalTime { get; set; }
}

public class SearchForFlight
{
    public SearchForFlight()
    {
        JourneyList = new List<SelectListItem>();
        FlightCabinClassList = new List<SelectListItem>();
        Segments = new otherType();
    }
    public string EndUserIp { get; set; }
    public string TokenId { get; set; }
    public int AdultCount { get; set; }
    public int ChildCount { get; set; }
    public int InfantCount { get; set; }
    public bool DirectFlight { get; set; }
    public bool OneStopFlight { get; set; }
    public JourneyType JourneyType { get; set; }
    public string PreferedLines { get; set; }
    public otherType Segments { get; set; }
    [JsonIgnore]
    public IEnumerable<SelectListItem> FlightCabinClassList { get; set; }
    [JsonIgnore]
    public IEnumerable<SelectListItem> JourneyList { get; set; }
    public string Sources { get; set; }
}

The following code populates my model correctly, but if I include the square brackets, binding fails.

<script>
    $(document).ready(function () {                 
        $("#btnPost").click(function () {
            var sof = {
                AdultCount: $("#AdultCount").val(),
                JourneyType: $("#JourneyType :selected").text(),
                PreferredAirlines: null,
                Segments:
                {
                    Origin: $("#Segments_Origin").val(),
                    Destination: $("#Segments_Destination").val(),
                    FlightCabinClass: $("#FlightCabinClass").val(),
                    PreferredDepartureTime: $("#Segments_PreferredDepartureTime").val(),
                    PreferredArrivalTime: $("#Segments_PreferredArrivalTime").val(),
                }
            };

Controller

[System.Web.Http.HttpPost]
public async Task<HttpResponseMessage> SearchFlight([FromBody]SearchForFlight sof)
{
    string url = "http://api.tektravels.com/BookingEngineService_Air/AirService.svc/rest/Search/";
    using (HttpClient client = new HttpClient())
    {
        .....
    }
}

How do I generate the correct format and bind to the model?

7
  • Based on the model in your link, Segments is an object (typeof otherType) not a collection of objects) so you cannot generate a collection using [ ... ]. What to you mean the according to documentation? Are you posting to an API that requires the property Segments to be a collection? (in which case you need to change your model) Commented May 19, 2016 at 6:46
  • According to documents means sample request/response provided by travel portal to talk to their rest api. The sample Request is here: pastebin.com/2n7ZjsBE Now how should i modify my model sir?? @StephenMuecke Commented May 19, 2016 at 7:02
  • You need to edit your question with that information, plus the model (links to code are not acceptable). But basically your property needs to be public IEnumerable<otherType> Segments { get; set; } and use the code in your first snippet. Of course this would all be far easier if you just used $('form').serialize(); rather than manually building your object. Commented May 19, 2016 at 7:07
  • I have edited the question to make it a bit clearer what your wanting to do. I'll add an answer in about 30 min :) Commented May 19, 2016 at 7:26
  • Edited my ques, changed property to public IEnumerable<otherType> Segments { get; set; } now, in constructor of model any change needed?? and what would be here @Html.LabelFor(model => model.Segments., htmlAttributes: new { @class = "control-label col-md-2" }) and where to use $('form').serialize(); Commented May 19, 2016 at 7:27

1 Answer 1

1

The API format means the the Segments property must be a collection of otherType (your model only has a single object). In addition the Sources property is also a collection of string.

Change you model to

public class SearchForFlight
{
    public SearchForFlight()
    {
        Segments = new List<otherType>();
        Sources = new List<string>();
    }
    ....
    public string PreferedLines { get; set; }
    public List<otherType> Segments { get; set; }
    [JsonIgnore]
    public IEnumerable<SelectListItem> FlightCabinClassList { get; set; }
    [JsonIgnore]
    public IEnumerable<SelectListItem> JourneyList { get; set; }
    public List<string> Sources { get; set; }
}

and then assuming your only wanting to edit one Segments and one Sources, then in the GET method, add one object to each collection

SearchForFlight model = new SearchForFlight();
model.Segments.Add(new otherType());
model.Sources.Add(string.Empty);
....
return View(model);

and in the view, use for loops to generate the html for the collections

@for(int i = 0; i < Model.Segments.Count; i++)
{
    @Html.LabelFor(m => m.Segments[i].Origin)
    @Html.TextBoxFor(m => m.Segments[i].Origin)
    @Html.ValidationMesageFor(m => m.Segments[i].Origin)
    .... // other properties of otherType
}

Note that this will generate id attributes such as id="Segments_0__Origin" so your script would need to be

Segments:
{
    Origin: $("#Segments_0__Origin").val(),
    Destination: $("#Segments_0__Destination").val(),
    ....

however there is no need to generate you javascript object manually, and your ajax can be simply

$.ajax({
    ....
    data: $('form').serialize(),
    ....

and do not set the contentType option so it uses the default application/x-www-form-urlencoded; charset=UTF-8

Sign up to request clarification or add additional context in comments.

10 Comments

model.Segments.Add(new otherType()); problem at this line 'System.Collections.Generic.IEnumerable<xx.Models.OtherType>' does not contain a definition for 'Add' and no extension method 'Add' accepting a first argument of type Error
Its public List<otherType> Segments { get; set; } (not IEnumerable<otherType>)
Only value of FlightCabinClass which is a dropdown is correct in posted data to web api controller but all other properties are still null @Stephen Muecke
Using which option - .serialize() or Origin: $("#Segments_0__Origin").val(),? If its not binding, its because your view is wrong or your using the wrong jquery selectors (check the actual id attributes of the elements)
but one problem still, some properties for like EndUserIp I have to send default value 192.168.10.10 So, is it possible with $('form').serialize()
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.