0

I am trying to build an ASP.NET MVC application I want to return a model instead of json but I need help to use to model to fill my datatable.

Here is my Javascript:

   @section Scripts{
        <script type="text/javascript" charset="utf8" src="~/Scripts/DataTables/jquery.dataTables.js"></script>
        <script>
            $(document).ready(function () {
                $('#proveedorContactoTable').DataTable({
                    "ajax": {
                        "url": "/fichaProveedor/loadProveedorContactoTable",
                        "type": "GET",
                        "datatype": "json"
                    },
                    "columns": [
                        { "data": "nombre_contacto", "autoWidth": true }, /* index = 0 */
                        { "data": "apellido_contacto", "autoWidth": true }, /* index = 1 */
                        { "data": "carga_contacto", "autoWidth": true }, /* index = 2 */
                        { "data": "telefono_fijo_contacto", "autoWidth": true }, /* index = 3 */
                        { "data": "telefono_movil_contacto", "autoWidth": true }, /* index = 4 */
                        { "data": "correo_contacto", "autoWidth": true }, /* index = 5 */
                        { "data": "principal", "autoWidth": true }, /* index = 6 */
                        {
                            "data": "contacto_id", "width": "50px", "render": function (data) {
                                return '<a class="popup" href="/fichaProveedor/Detalles/' + data + '">Editar</a>';  /* index = 7 */
                            }
                        },
                        {
                            "data": "contacto_id", "width": "50px", "render": function (data) {

                                return '<a class="btn btn-primary" href="/fichaProveedor/Eliminar/' + data + '">Eliminar</a>'; /* index = 8 */
                            }
                        }
                    ],
                    'columnDefs': [{
                        'targets': [7, 8], /* column index */
                        'orderable': false, /* true or false */
                    }]
                });
            });

        </script>
    }

And here is my html table

<div class="dvScroll">
    <table id="myTable">
        <thead>
            <tr>
                <th>Proveedor Id</th>
                <th>Nombre</th>
                <th>Dirección</th>
                <th>Código postal</th>
                <th>Cuidad</th>
                <th>País</th>
                <th>Pagina internet</th>
                <th>Edit</th>
                <th>Delete</th>
            </tr>
        </thead>
    </table>
</div>

I have the following model that contains a list of "contactos" I want to use all its elements to fill the jQuery table. Here is my model and some of the properties contained in the model.

@model erp_colombia.Models.proveedorModel
@foreach (var contacto in Model.contactos)
{
        @contacto.contacto_id
        @contacto.apellido_contacto
}

Here is my controller so far

[HttpPost]
public ActionResult Editar(inventarioModel gestiondeubicacione)
{
    inventarioContext gestiondeubicaciones = new inventarioContext();
    bool status = false;
    if (ModelState.IsValid)
    {
        if (gestiondeubicacione.componente_id > 0)
        {
            //Edit 
            var gestiondeubicacionesFound = gestiondeubicaciones.GetAllInventarios().Where(a => a.componente_id == gestiondeubicacione.ubicacion_id).FirstOrDefault();
            if (gestiondeubicacionesFound != null)
            {
                gestiondeubicacionesFound.armario = gestiondeubicacione.armario;
                gestiondeubicacionesFound.cajon = gestiondeubicacione.cajon;
            }
        }
        else
        {
            //gestiondeubicaciones.addInvenotryLocationToDB(gestiondeubicacione);
            TempData["msgType"] = messageType.success;
            TempData["msg"] = "Nueva ubicación agregada!";
            //Save new one
            //dc.Employees.Add(emp);
        }
        //gestiondeubicaciones.updateInvenotryLocationToDB(gestiondeubicacione);
        TempData["msgType"] = messageType.success;
        TempData["msg"] = "La ubicación ha sido actualizada!";
        //Update
        //dc.SaveChanges();
        status = true;
    }
    return new JsonResult { Data = new { status = status } };
}

How can I use my model inside the Javascript instead of the json? Thank you very much for your help.

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
J.C
  • 632
  • 1
  • 10
  • 41
  • 1
    If '/fichaProveedor/loadProveedorContactoTable' is a WebAPI, then it will return JSON by default instead of a model.. If it is a normal view then You can convert model to JSON using `JsonConvert.SerializeObject` like `var json = JsonConvert.SerializeObject(Model.contactos);` – Mohamed Farouk Jan 15 '20 at 00:24
  • @MohamedFarouk yes that is exacly what I want to do but I dont know how in my context. Where in my script must I add the code and what more most I modifie. – J.C Jan 15 '20 at 00:31
  • I added the simplest way to do it.. View has only HTML.. backend has no view and sends back JSON – Mohamed Farouk Jan 15 '20 at 01:05
  • 1
    @JuniorCortenbach, in the controller the return should be `return View(model)` – Ajeet Kumar Jan 15 '20 at 02:01
  • Yes @AjeetKumar that is exaclty what I want to to but I am using jquery datable wich require a json file. However I also need to model. Therefore I want to convert the model to json in the script section. – J.C Jan 15 '20 at 02:03
  • 1
    A "model" is a data structure. You have to "serialise" it to something to send it as a message (in the case a HTTP result). JSON is the serialisation format that most people use nowadays when sending data structures as a message around the web. In your question you write "here is my model" then you have some sample code but this code is not a "model". It's just razor code that consumes a model. So take a step back and please explicitly explain what issue you have with consuming JSON in a datatable. What is the actual issue? You don't like the format? you get an error? – Nick.Mc Jan 15 '20 at 02:07
  • @Nick.McDermaid I am using https://datatables.net/ to make my table this requires json. However I need a model in my razor and not json beacause latter I want to use the model in a new view. Therefore I would like to somehow modifie my jquery code so it can use my model insted of json. – J.C Jan 15 '20 at 02:15
  • 1
    Your jquery code does use your model. It just happens to be "serialised" as JSON. What is stopping you using "a model in my razor" right now? I think the issues is that you need two different controllers, one for your datatable (which returns JSON), and one for your razor view (which returns actionresult). They _both_ use the same underlying "model" (in MVC terms) but the controller emits two different kinds of results. One that is just JSON, the other that can be used by Razor. The question is: do you want both on the same page? – Nick.Mc Jan 15 '20 at 02:29
  • Yes @Nick.McDermaid you are rigth the issues is that I need two different controllers, one for your datatable (which returns JSON). I only want on return that should return a view NOT json. Then after words once I have my model in razor I want to use it to make it json in my jquery script. But I dont know how to do it. – J.C Jan 15 '20 at 02:34
  • 1
    This is interesting: https://stackoverflow.com/questions/16361364/accessing-mvcs-model-property-from-javascript You can write javascript that accesses the MVC model. But it needs to be in the .cshtml to be able to access the razor variable. Also it is evaluated completely on the server then returned to the client which means any async / ajax benefit you have from `DataTable` will be lost. – Nick.Mc Jan 15 '20 at 02:39
  • 1
    Basically you use that to load the model into a javascript variable (in JSON form). Then you just have to work out how to use that variable as a source in datatable. If you get this working, _please_ post back a detailed answer because I reckon quite a few people are confused by this. – Nick.Mc Jan 15 '20 at 02:40
  • Yes I will @Nick.McDermaid the reason why I need this is beacouse I want to solve the problem that I have here https://stackoverflow.com/questions/59708648/how-to-return-json-data-from-mvc-controller-and-view – J.C Jan 15 '20 at 02:44
  • If that is your objective (having a popup based on a click), then this javascript trick will not work because it's all done server side. I commented in your other post on this topic. – Nick.Mc Jan 15 '20 at 07:03

1 Answers1

0
  1. JSON Controller
[Route("fichaProveedor")]
public class ReportingController : ControllerBase 
{
       [HttpGet("loadProveedorContactoTable")]
        public async Task<IActionResult> LoadProveedorContactoTable()
        {
           var erp_colombia = //load result here
           return Ok(erp_colombia.Models.proveedorModel);
        }
}
  1. WebAPI client View
<script type="text/javascript" charset="utf8" src="~/Scripts/DataTables/jquery.dataTables.js"></script>
<table id="proveedorContactoTable" class="display" style="width:100%">
</table>
        <script>
            $(document).ready(function () {
                $('#proveedorContactoTable').DataTable({
                    "ajax": {
                        "url": "/fichaProveedor/loadProveedorContactoTable",
                        "type": "GET",
                        "datatype": "json"
                    },
                    "columns": [
                        { "data": "nombre_contacto", "autoWidth": true }, /* index = 0 */
                        { "data": "apellido_contacto", "autoWidth": true }, /* index = 1 */
                        { "data": "carga_contacto", "autoWidth": true }, /* index = 2 */
                        { "data": "telefono_fijo_contacto", "autoWidth": true }, /* index = 3 */
                        { "data": "telefono_movil_contacto", "autoWidth": true }, /* index = 4 */
                        { "data": "correo_contacto", "autoWidth": true }, /* index = 5 */
                        { "data": "principal", "autoWidth": true }, /* index = 6 */
                        {
                            "data": "contacto_id", "width": "50px", "render": function (data) {
                                return '<a class="popup" href="/fichaProveedor/Detalles/' + data + '">Editar</a>';  /* index = 7 */
                            }
                        },
                        {
                            "data": "contacto_id", "width": "50px", "render": function (data) {

                                return '<a class="btn btn-primary" href="/fichaProveedor/Eliminar/' + data + '">Eliminar</a>'; /* index = 8 */
                            }
                        }
                    ],
                    'columnDefs': [{
                        'targets': [7, 8], /* column index */
                        'orderable': false, /* true or false */
                    }]
                });
            });

        </script>
  1. MVC Controller
[Route("fichaProveedor")]
public class ReportingController : ControllerBase 
{
       [HttpGet("loadProveedorContactoTable")]
        public ActionResult LoadProveedorContactoTable()
        {
           var erp_colombia = //load result here
           return erp_colombia.Models.proveedorModel;
        }
}
  1. WebAPI client View
    <script type="text/javascript" charset="utf8" src="~/Scripts/DataTables/jquery.dataTables.js"></script>
@model erp_colombia.Models.proveedorModel
    <table id="proveedorContactoTable" class="display" style="width:100%">
      @foreach (var contacto in Model.contactos)
{
        <tr><td>@contacto.contacto_id</td>
        <td>@contacto.apellido_contacto</td></tr>
}
    </table>
            <script>
                $(document).ready(function () {
                    $('#proveedorContactoTable').DataTable({
                        "columns": [
                            { "data": "nombre_contacto", "autoWidth": true }, /* index = 0 */
                            { "data": "apellido_contacto", "autoWidth": true }, /* index = 1 */
                            { "data": "carga_contacto", "autoWidth": true }, /* index = 2 */
                            { "data": "telefono_fijo_contacto", "autoWidth": true }, /* index = 3 */
                            { "data": "telefono_movil_contacto", "autoWidth": true }, /* index = 4 */
                            { "data": "correo_contacto", "autoWidth": true }, /* index = 5 */
                            { "data": "principal", "autoWidth": true }, /* index = 6 */
                            {
                                "data": "contacto_id", "width": "50px", "render": function (data) {
                                    return '<a class="popup" href="/fichaProveedor/Detalles/' + data + '">Editar</a>';  /* index = 7 */
                                }
                            },
                            {
                                "data": "contacto_id", "width": "50px", "render": function (data) {

                                    return '<a class="btn btn-primary" href="/fichaProveedor/Eliminar/' + data + '">Eliminar</a>'; /* index = 8 */
                                }
                            }
                        ],
                        'columnDefs': [{
                            'targets': [7, 8], /* column index */
                            'orderable': false, /* true or false */
                        }]
                    });
                });

            </script>
Mohamed Farouk
  • 1,089
  • 5
  • 10
  • I should have added my controller I am using ActionResult will your solution still work? – J.C Jan 15 '20 at 01:16
  • Also ok does not exist in current context. – J.C Jan 15 '20 at 01:24
  • 1
    `[HttpGet("loadProveedorContactoTable")] public ActionResult LoadProveedorContactoTable() { var erp_colombia = //load result here return Ok(erp_colombia.Models.proveedorModel); }` This should work too – Mohamed Farouk Jan 15 '20 at 01:24
  • 1
    Can you replace `Ok` with return `Json(erp_colombia.Models.proveedorModel);` OR `Request.CreateResponse(HttpStatusCode.OK,erp_colombia.Models.proveedorModel,Configuration.Formatters.JsonFormatter);` ? – Mohamed Farouk Jan 15 '20 at 01:27
  • I got your solution to work but it is not want I want to return a Model not json. In javascript I want to transform the model in razor where the javascript is. Beacouse I cannot return json and model. – J.C Jan 15 '20 at 01:44
  • mmm. then `"ajax": { "url": "/fichaProveedor/loadProveedorContactoTable", "type": "GET", "datatype": "json" }` is not possible.. you can construct HTML table from your model and have a normal View and use the simple `$(document).ready(function() { $('#example').DataTable(); } );` plus your cols configuration – Mohamed Farouk Jan 15 '20 at 01:51
  • I added MVC mode too – Mohamed Farouk Jan 15 '20 at 01:55