Click here to Skip to main content
15,891,749 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hi,

I have the following scenario: I have a controller for model "Customers". In "Create" view I have a form for adding customers in DB. I succeed to do the following task: after entering a certain value in an editbox of form, by clicking a dedicated button I invoke a method in my controller passing the textvalue of editbox as parameter and on brief the method make a web-request against a given web-server and finally returns a JSON that contain data that I need for my form (e.g. I search for a given company registration number and in JSON I find name, address, email, phone etc.). Furthermore after this in my method I bind the information within JSON to my model (at this step all is tested and is fine, I have all data that I need).

What I want now is to "send" this data to the each form element and to prefill them before sending/saving form (in final version there will be also a number of editboxes that are not covered by info obtained from JSON and that I may manually write in form)

So for summarize, in CustomersControler I have three actions that concerns this: GetCompanyInfo (this retrieve a JSON from a web-server based on parameter from form in view), Create (GET version) and Create (POST version) (last two scafolded by Visual Studio)
I provide bellow the relevant code.
First in CutomersController (I modified after first ask of question):

C#
public class CustomersController : Controller
    {
        private InvoiceDBEntities db = new InvoiceDBEntities();
        public Customers cModel = new Customers();
        //Ask the web for company details
        public ActionResult GetCompanyInfo(string CompanyNumber)
        {
            //call for openapi.ro //pc94 srl: RO5949570 infosystems4u: 22052442
            string CompanyCUI = CompanyNumber;
            // Create a new 'Uri' object with the specified string.
            Uri myUri = new Uri("https://api.openapi.ro/api/companies/" + CompanyCUI + ".json");
            // Create a new request to the above mentioned URL. 
            WebRequest myWebRequest = WebRequest.Create(myUri);
            //Add the required header to request
            myWebRequest.Headers.Add("x-api-key", "8P4RP_kwn71Nt8VG7boFmQb_7NsihyQxT_x7JGcGQkvPdXZH2Q");
            // Assign the response object of 'WebRequest' to a 'WebResponse' variable.
            WebResponse myWebResponse = myWebRequest.GetResponse();
            // Read the response into a stream
            var dataStream = myWebResponse.GetResponseStream();
            var reader = new StreamReader(dataStream);
            var jsonResultString = reader.ReadToEnd();
            // Deserialize
            var CompanyInfoData = Newtonsoft.Json.JsonConvert.DeserializeObject<CustomerModels>(jsonResultString);
            //Bind to model for feed him (not all properties, just for illustrating)
            
            cModel.Phone1 = CompanyInfoData.telefon;
            cModel.CompanyRegistration = CompanyInfoData.numar_reg_com;
            cModel.Name = CompanyInfoData.denumire;
            cModel.CompanyNumber = CompanyInfoData.cif;
            cModel.Address = CompanyInfoData.adresa;

            ViewData["Customer"] = cModel;
            //Create();
            //original when asked the question
            return View("Create", cModel);
            //modified version
            return Json(CompanyInfoData,JsonRequestBehavior.AllowGet);
        }

        // GET: Customers
        public ActionResult Index()
        {
            //This is only for testing purpose for demonstrate the behavior desired
            //call for openapi.ro //pc94 srl: RO5949570 infosystems4u: 22052442
            string CompanyCUI = "22052442";
            // Create a new 'Uri' object with the specified string.
            Uri myUri = new Uri("https://api.openapi.ro/api/companies/" + CompanyCUI + ".json");
            // Create a new request to the above mentioned URL. 
            WebRequest myWebRequest = WebRequest.Create(myUri);
            //Add the required header to request
            myWebRequest.Headers.Add("x-api-key", "8P4RP_kwn71Nt8VG7boFmQb_7NsihyQxT_x7JGcGQkvPdXZH2Q");
            // Assign the response object of 'WebRequest' to a 'WebResponse' variable.
            WebResponse myWebResponse = myWebRequest.GetResponse();
            // Read the response into a stream
            var dataStream = myWebResponse.GetResponseStream();
            var reader = new StreamReader(dataStream);
            var jsonResultString = reader.ReadToEnd();
            // Deserialize
            var CompanyInfoData = Newtonsoft.Json.JsonConvert.DeserializeObject<CustomerModels>(jsonResultString);
            //Bind to model for feed him
            //
            var cModel = new CustomerModels();

            cModel.Phone1 = CompanyInfoData.telefon;
            cModel.CompanyRegistration = CompanyInfoData.numar_reg_com;
            cModel.Name = CompanyInfoData.denumire;
            cModel.CompanyNumber = CompanyInfoData.cif;
            cModel.Address = CompanyInfoData.adresa;

            ViewData["Customer"] = cModel;
            return View(cModel);
            //default behavior of original view
            //return View(db.Customers.ToList());
        }

        // GET: Customers/Create
        public ActionResult Create()
        {
            return View(cModel);
        }

        // POST: Customers/Create
        // To protect from overposting attacks, please enable the specific properties you want to bind to, for 
        // more details see http://go.microsoft.com/fwlink/?LinkId=317598.
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Create([Bind(Include = "CustomerID,Name,CompanyNumber,CompanyRegistration,CompanyBank,CompanyIBAN,Address,CP,City,ContactPerson,Phone1,Phone2,Fax,Email,Notes")] Customers customers)
        {

            if (ModelState.IsValid)
            {
                db.Customers.Add(customers);
                db.SaveChanges();
                return RedirectToAction("Index");
            }

            return View(customers);
        }

        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                db.Dispose();
            }
            base.Dispose(disposing);
        }
    }


a briefly preview of the model (not necessarily relevant, it may change, but just in case)

C#
public Customers()
        {
            this.Invoices = new HashSet<Invoices>();
        }
    
        public int CustomerID { get; set; }
        public List<object> tva_la_incasare { get; set; }
        public string Name { get; set; }
        public string CompanyNumber { get; set; }
        public string CompanyRegistration { get; set; }
        public string CompanyBank { get; set; }
        public string CompanyIBAN { get; set; }
        public string Address { get; set; }
        public string CP { get; set; }
        public string City { get; set; }
        public string ContactPerson { get; set; }
        public string Phone1 { get; set; }
        public string Phone2 { get; set; }
        public string Fax { get; set; }
        public string Email { get; set; }
        public string Notes { get; set; }
    
        public virtual ICollection<Invoices> Invoices { get; set; }


and now in Create.cshtml view (razor code and at the end script used)

HTML
@using ChameleonForms
@using ChameleonForms.Component
@using ChameleonForms.Enums
@using ChameleonForms.Templates
@using ChameleonForms.ModelBinders

@model DirectInvoice.Models.Customers

@{
    ViewBag.Title = "Create";
}

<h2>Create Customer</h2>
<p>Use for test e.g. pc94 srl: RO5949570 or infosystems4u srl: 22052442</p>

<div>
    @using (var f = Html.BeginChameleonForm())
    {
        @Html.AntiForgeryToken()
        using (var s = f.BeginSection("Add a new customer"))
        {
            @s.FieldFor(m => m.CompanyNumber)
            @*First approach that don't work*@
            @*<button type="button" onclick="location.href='@Url.Action("GetCompanyInfo", "Customers", new { id = "Ask" })'" class="btn btn-default">Ask the web!</button>*@
            <button id="Ask" type="button" class="btn btn-default">Ask the web!</button>
            @s.FieldFor(m => m.Name)
            @s.FieldFor(m => m.CompanyRegistration)
            @s.FieldFor(m => m.Address)
            @s.FieldFor(m => m.City)
            @s.FieldFor(m => m.Phone1).Placeholder("0XX X XXX XXX")

        }
        using (var n = f.BeginNavigation())
        {
            @n.Submit("Save the new customer...")
        }
    }
</div>

<div>
    @Html.ActionLink("Back to List", "Index")
</div>

@section Scripts {

    <script type="text/javascript">
        $('#Ask').click(function () {

            var companynumber = $('#CompanyNumber').val();

            $.ajax({
                type: 'POST',
                data: {
                    CompanyNumber: companynumber
                },
                //url from the controller's action method e.g. GetCompanyInfo
                url: '/Customers/GetCompanyInfo/?CompanyNumber=' + $('#CompanyNumber').val(),
                //dataType: 'json',
                //contentType: "application/json; charset=utf-8",

                //Later edit of the code
                dataType: "html",
                contentType: "application/x-www-form-urlencoded; charset=UTF-8",

                success: function (data) {
                    //Here you would update the textboxes, the 'data'
                    //variable contains the html from the partialview

                    //Later edit of the code
                    $('#CompanyNumber').html(data.numar_reg_com);
                    $('#Name').html(data.denumire);
                    $('#Address').html(data.adresa);
                    $('#Phone1').html(data.telefon);
                },
                error: function () {
                    //Manage errors
                }
            });

        }
    )
    </script>

}


Hope that all above helps. Any hint about how to pre fill the form elements with data from the JSON retrieved, will be very appreciated.

I add also a print-screen with what I get now (with some little explanations of operational flow):

https://dl.dropboxusercontent.com/u/23409498/Printscreens/2016-09-06%20(3).png[^]

Thank you

What I have tried:

Various variants of javascript, also to call Create() (GET version) method in my GetCompanyInfo, and also modified by first suggestion that I get. Still don't work.
Posted
Updated 5-Sep-16 23:36pm
v3

1 solution

JavaScript
success: function(data){
    $('#CompanyNumber').val(data.numar_reg_com); // $('#CompanyNumber').html is not the same as .val().
    //etc...
}


Please make sure you configure the $ajax call correctly:
JavaScript
dataType: "json", // The type of data expected back
contentType: "application/x-www-form-urlencoded; charset=UTF-8" // The type of data sent to action


Also, the reason it's not working is because you cant put data and url querystring together in same ajax call, remove the query string "$('#companynumber') from the url: ajax property, leave it in the data: property.

When MVC controller receives the request, jQuery will automatically convert the data: property to url querystring and append it for MVC to receive.

use
JavaScript
console.log()
in your JS code and view the browser console window (F12) to see exactly what URL and QueryStrings are being sent to the server and use it to debug your client side code.

I suggest you learn jQuery in depth and how it works before trying random combinations of config and usage.jQuery.ajax() | jQuery API Documentation[^]
 
Share this answer
 
v2
Comments
Laurentiu LAZAR 6-Sep-16 5:08am    
So for being sure that I understand well:
$('#CompanyNumber').html(data.numar_reg_com);
$('#Name').html(data.denumire);
$('#Address').html(data.adresa);
$('#Phone1').html(data.telefon);
and so on... ?
njammy 6-Sep-16 5:43am    
This code will not work. You are assigning HTML content to html input fields, which require plain text, not html. I thought from your original question you want to display html returned from a ajax call? then is totally the opposite of what you want to do.

Looking back at your code, your method GetcompanyInfo is returning JSON data not html.

you need to change the ajax call config like my updated answer, and set the field values in the udpated logic in the answer.
Laurentiu LAZAR 6-Sep-16 5:12am    
I try this but it does nothing. My method returns the desired JSON content, but nothing is then updated on my form.
Laurentiu LAZAR 6-Sep-16 5:52am    
I did not see your updated answer.
Laurentiu LAZAR 6-Sep-16 6:02am    
Now is work exactly how I expect, even with query string attached.
Just wonder if detail that I provided regarding the fact that the final, real model will have more properties than the fields in JSON may interfere? Normally I suppose that not.
Also I think that it becomes obsolete what I do in my method for assigning values from JSON to model.

Thank you very much!

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900