Return the data to the View using Json.net or javascript- asp.net mvc

0

I need to return the data to fill a script,

        public JsonResult BuscaImagens()
        {
            List<Object> resultado = new List<object>();
            resultado.Add(new
            {
                IdImagem = 1,
                URL = "~/Content/img/galeriaimagens/sl1.jpg"
            });
            resultado.Add(new
            {
                IdImagem = 2,
                URL = "~/Content/img/galeriaimagens/sl2.jpg"
            });
            resultado.Add(new
            {
                IdImagem = 3,
                URL = "~/Content/img/galeriaimagens/sl3.jpg"
            });
            return Json(resultado, JsonRequestBehavior.AllowGet);
        }

I now have:

        public ActionResult LerDadosJson()
        {
            return View();
        }

In View ReadersJson:

<script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-3.1.1.js"></script><script>$(function(){$.ajax({dataType:"json",
            type: "GET",
            url: "/Home/BuscaImagens",
            success: function (dados) {
                $(dados).each(function (i) {
                    document.writeln("<p>Id: " + dados[i].IdImagem + " | URL: " + dados[i].URL + "</p>")
                });
            }
        });
    });
</script>

Feedback is like this

IneedthisformatthatisintheinitialPreviewandinitialPreviewConfig:

<script>$("#Image1").fileinput({
    uploadUrl: "@Url.Action("upload", "Home")",
    uploadAsync: false,
    minFileCount: 2,
    maxFileCount: 5,
    overwriteInitial: false,
    initialPreview: [
        "<img style='height:160px' [email protected]("~/Content/img/galeriaimagens/sl1.jpg")>",
        "<img style='height:160px' [email protected]("~/Content/img/galeriaimagens/sl1.jpg")>",
        "<img style='height:160px' [email protected]("~/Content/img/galeriaimagens/sl1.jpg")>",
        "<img style='height:160px' [email protected]("~/Content/img/galeriaimagens/sl1.jpg")>",
    ],
    initialPreviewConfig: [
        { caption: "Food-1.jpg", size: 329892, width: "120px", url: "@Url.Action("remover", "Home")", key: 1 },
        { caption: "Food-2.jpg", size: 872378, width: "120px", url: "@Url.Action("remover", "Home")", key: 2 },
        { caption: "Food-3.jpg", size: 632762, width: "120px", url: "@Url.Action("remover", "Home")", key: 3 },
        { caption: "Food-4.jpg", size: 632762, width: "120px", url: "@Url.Action("remover", "Home")", key: 4 },
    ],
    uploadExtraData: {
        img_key: "1000",
        img_keywords: "happy, nature",
    }
});
$("#Image1").on("filepredelete", function (jqXHR) {
    var abort = true;
    if (confirm("Tem certeza de que deseja apagar esta imagem?")) {
        abort = false;
    }
    return abort; // you can also send any data/object that you can receive on 'filecustomerror' event
});
</script>
    
asked by anonymous 23.10.2016 / 23:05

1 answer

1

To create the script already with initialPreview completed you do not have to create a method that returns JSON. It will be more efficient to modify the View that today generates the page to use a template, and in that template generate that script dynamically. There are several ways to implement this result. I'll do the most up-to-date first.

ViewBag

Let's fill ViewBag , a dynamic item that can be filled with all data type and is available to the page rendering engine, in this case Razor. As we are using this simpler way of passing data to the View, I have added the Image class directly in HomeController (in this case the controller name and action will certainly be different!):

public class HomeController : Controller
{
    public class Imagem
    {
        public int Id { get; set; }
        public string Url { get; set; }
    }

    public ActionResult Index() {
        // usando ViewBag... (propriedade dinâmica)
        ViewBag.Images = new List<Imagem> {
            new Imagem { Id = 1, Url = Url.Content("~/Content/img/galeriaimagens/sl1.jpg") },
            new Imagem { Id = 2, Url = Url.Content("~/Content/img/galeriaimagens/sl2.jpg") },
            new Imagem { Id = 3, Url = Url.Content("~/Content/img/galeriaimagens/sl3.jpg") },
        };
        return View();
    }

And then in the view we use ViewBag.Images to render the list of urls we'll put in the initial preview . Note that you should set the using clause at the beginning of the script to use the controller where you defined the class Imagem :

@using SO_InitialPreviewMVC.Controllers;
@{
    ViewBag.Title = "Home Page";
    // estou já convertendo para o tipo específico para facilitar mais embaixo
    var imgs = ViewBag.Images as List<HomeController.Imagem>;
}

<script>

  $("#Image1").fileinput({
    uploadUrl: "@Url.Action("upload", "Home")",
    uploadAsync: false,
    minFileCount: 2,
    maxFileCount: 5,
    overwriteInitial: false,
    initialPreview: [
        @* Aqui using string.Join para montar os itens do array, tem um milhão de formas de fazer isso! *@
        @Html.Raw(string.Join(",\r\n        ", 
            imgs.Select(img => "\"<img style='height:160px' src='" + img.Url + "'>\"")))
    ],
    initialPreviewConfig: [
        { caption: "Food-1.jpg", size: 329892, width: "120px", url: "@Url.Action("remover", "Home")", key: 1 },
        { caption: "Food-2.jpg", size: 872378, width: "120px", url: "@Url.Action("remover", "Home")", key: 2 },
        { caption: "Food-3.jpg", size: 632762, width: "120px", url: "@Url.Action("remover", "Home")", key: 3 },
        { caption: "Food-4.jpg", size: 632762, width: "120px", url: "@Url.Action("remover", "Home")", key: 4 },
    ],
    uploadExtraData: {
            img_key: "1000",
        img_keywords: "happy, nature",
    }
  });
</script>

The rest of the view code has been omitted ... I left enough to understand where the changes were made.

View Model

This is what I would indicate as the best way. Let's create a template that we'll call View Model because it's the "vision" model and not the business model. It is used to facilitate view rendering and even carry validation information (in rare cases) and other things.

Let's add the HomeViewModel class in the Models directory of your solution:

public class HomeViewModel
{
    public HomeViewModel() {
        // apenas para garantir que NUNCA seja nulo! Facilica código na view
        PreviewImages = new List<Imagem>();
    }
    public List<Imagem> PreviewImages { get; set; }
}

Add in the namespace of your application! Use instead of "Home" the name of your View to maintain consistency !!!

Add in Models the same Image class (which we removed from HomeController, since it will now be used by our HomeViewModel and probably other view models !):

public class Imagem
{
    public int Id { get; set; }
    public string Url { get; set; }
}

Modify the controller method to pass the template to the heavily typed view:

... 
// adicione o using do seus Models (seu namespace será outro!!!)
using SO_InitialPreviewMVC.Models;
...
public ActionResult Index() {
    // usando um modelo específico para a view
    var model  = new HomeViewModel { 
        PreviewImages = new List<Imagem> {
            new Imagem { Id = 1, Url = Url.Content("~/Content/img/galeriaimagens/sl1.jpg") },
            new Imagem { Id = 2, Url = Url.Content("~/Content/img/galeriaimagens/sl2.jpg") },
            new Imagem { Id = 3, Url = Url.Content("~/Content/img/galeriaimagens/sl3.jpg") },
        }
    };
    // passamos o modelo criado para a view
    return View(model);
}

Now modify the view so that it is strongly typed:

@model SO_InitialPreviewMVC.Models.HomeViewModel
@{
    ViewBag.Title = "Home Page";
}

<script>

  $("#Image1").fileinput({
    uploadUrl: "@Url.Action("upload", "Home")",
    uploadAsync: false,
    minFileCount: 2,
    maxFileCount: 5,
    overwriteInitial: false,
    initialPreview: [
        @* Aqui using string.Join para montar os itens do array, tem um milhão de formas de fazer isso! *@
        @Html.Raw(string.Join(",\r\n        ",
            Model.PreviewImages.Select(img => "\"<img style='height:160px' src='" + img.Url + "'>\"")))
    ],

Again, the namespace of @model will be another!

See that we no longer use a dynamic field like ViewBag and we even have code completion suggestion when typing Model. ... You will see that the PreviewImages property will appear.

Result The markup generated for both solutions is equal and follows the part only of the <script> itself:

<script>

  $("#Image1").fileinput({
    uploadUrl: "/Home/upload",
    uploadAsync: false,
    minFileCount: 2,
    maxFileCount: 5,
    overwriteInitial: false,
    initialPreview: [

        "<img style='height:160px' src='/Content/img/galeriaimagens/sl1.jpg'>",
        "<img style='height:160px' src='/Content/img/galeriaimagens/sl2.jpg'>",
        "<img style='height:160px' src='/Content/img/galeriaimagens/sl3.jpg'>"
    ],
    initialPreviewConfig: [
        { caption: "Food-1.jpg", size: 329892, width: "120px", url: "/Home/remover", key: 1 },
        { caption: "Food-2.jpg", size: 872378, width: "120px", url: "/Home/remover", key: 2 },
        { caption: "Food-3.jpg", size: 632762, width: "120px", url: "/Home/remover", key: 3 },
        { caption: "Food-4.jpg", size: 632762, width: "120px", url: "/Home/remover", key: 4 },
    ],
    uploadExtraData: {
            img_key: "1000",
        img_keywords: "happy, nature",
    }
  });
</script>
    
24.10.2016 / 22:02