Laurentiu LAZAR Ответов: 1

Отправка данных из json обратно для просмотра в MVC


Привет,

У меня такой сценарий: у меня есть контроллер для модели «Заказчики». В представлении «Создать» у меня есть форма для добавления клиентов в БД. Мне удалось выполнить следующую задачу: после ввода определенного значения в поле редактирования формы, нажав специальную кнопку, я вызываю метод в моем контроллере, передавая текстовое значение поля редактирования в качестве параметра, и вкратце метод делает веб-запрос против заданный веб-сервер и, наконец, возвращает JSON, содержащий данные, которые мне нужны для моей формы (например, я ищу регистрационный номер данной компании и в JSON нахожу имя, адрес, электронную почту, телефон и т. д.). Кроме того, после этого в моем методе я привязываю информацию в JSON к моей модели (на этом этапе все проверено и все в порядке, у меня есть все данные, которые мне нужны).

Теперь я хочу "отправить" эти данные в каждый элемент формы и предварительно заполнить их перед отправкой / сохранением формы (в окончательной версии также будет несколько полей редактирования, которые не покрываются информацией, полученной из JSON, и которые я могу вручную записать в форму)

Итак, для суммирования, в CustomersControler у меня есть три действия, которые касаются этого: GetCompanyInfo (это получение JSON с веб-сервера на основе параметра из формы в представлении), Create (GET version) и Create (POST version) (последние два scafolded Visual Studio)
Я предоставляю ниже соответствующий код.
Сначала в CutomersController (я модифицировал после первого вопроса):

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);
        }
    }


краткий предварительный просмотр модели (не обязательно релевантный, он может измениться, но на всякий случай)

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; }


а теперь в Create.cshtml view (код razor И в конце используется скрипт)

@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>

}


Надеюсь, что все вышесказанное поможет. Любая подсказка о том, как предварительно заполнить элементы формы данными из извлеченного JSON, будет очень оценена.

Я добавляю также печатный экран с тем, что получаю сейчас (с некоторыми небольшими объяснениями операционного потока):

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

Спасибо

Что я уже пробовал:

Различные варианты javascript, также вызывающие метод Create () (GET version) в моем GetCompanyInfo, а также модифицированные первым предложением, которое я получаю. Все равно не получится.

1 Ответов

Рейтинг:
7

njammy

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


Пожалуйста, убедитесь, что вы правильно настроили вызов $ajax:
dataType: "json", // The type of data expected back
contentType: "application/x-www-form-urlencoded; charset=UTF-8" // The type of data sent to action


Кроме того, причина, по которой он не работает, заключается в том, что вы не можете поместить данные и url querystring вместе в одном вызове ajax, удалите строку запроса "$('#companynumber') из свойства url: ajax, оставьте ее в свойстве data:.

Когда контроллер MVC получает запрос, jQuery автоматически преобразует свойство data: в url querystring и добавляет его для получения MVC.

использовать
console.log()
в вашем JS-коде и просмотрите окно консоли браузера (F12), чтобы точно увидеть, какие URL-адреса и строки запросов отправляются на сервер, и использовать его для отладки кода на стороне клиента.

Я предлагаю вам подробно изучить jQuery и то, как он работает, прежде чем пробовать случайные комбинации конфигурации и использования.на jQuery."Аякс" () | библиотека jQuery API документация[^]


Laurentiu LAZAR

Так что за то, что я уверен, что хорошо понимаю:
$('#CompanyNumber'). html (data. numar_reg_com);
$('#Name'). html(data. denumire);
$('#Address'). html(data. adresa);
$('#Phone1'). html(data. telefon);
и так далее? ..

njammy

Этот код не будет работать. Вы назначаете HTML-содержимое полям ввода html, которые требуют обычного текста, а не html. Я думал, что из вашего первоначального вопроса Вы хотите отобразить html, возвращенный из вызова ajax? тогда это совершенно противоположно тому, что вы хотите сделать.

Оглядываясь назад на ваш код, ваш метод GetcompanyInfo возвращает данные JSON, а не html.

вам нужно изменить конфигурацию вызова ajax, как мой обновленный ответ, и установить значения полей в логике udpated в ответе.

Laurentiu LAZAR

Я пытаюсь это сделать, но ничего не получается. Мой метод возвращает желаемое содержимое JSON, но затем ничего не обновляется в моей форме.

Laurentiu LAZAR

Я не видел вашего обновленного ответа.

Laurentiu LAZAR

Теперь это работает именно так, как я ожидаю, даже с прикрепленной строкой запроса.
Просто интересно, могут ли детали, которые я предоставил относительно того факта, что окончательная, реальная модель будет иметь больше свойств, чем поля в JSON, вмешаться? Обычно я предполагаю, что нет.
Кроме того, я думаю, что устаревает то, что я делаю в своем методе присвоения значений из JSON модели.

Большое спасибо!

njammy

Модель представления и JSON могут иметь совершенно разные свойства. Создайте свою модель представления только для данных, необходимых для этого http-ответа. и сделайте то же самое для объектов JSON. Нет необходимости копировать и повторно использовать модели представления, когда вам не нужны все поля.