3

I have a view, where I'm calling an ActionResult method, but putting a breakpoint in the method tells me it's not being called.

<div>
<ul class="list-group">
    @foreach (var item in Model)
    {
        <li class="list-group-item">
            <h4>Slide ID: @item.SlideId</h4>
            <p><i>Received: @item.TimeStamp</i></p>
            <div class="row">
                <div class="col-md-4">
                    <h4>@Html.ActionLink("View details", "Well", new {slideid = item.SlideId})</h4>
                    <img src="@Url.Action("Index", "Images", new {id = item.SlideId})"/> //This is where I want to call the method                       
                </div>
            </div>
        </li>
    }
</ul>

And here's the method:

public class ImagesController : Controller
{
    // GET: Images
    public ActionResult Index(string id)
    {
        byte[] imageData = new byte[0];
        string cs = "Data Source=" + "some path";

        using (SQLiteConnection con = new SQLiteConnection(cs))
        {
            string stm = "SELECT LastImage FROM Well WHERE SlideId = " + "'" + id + "'";
            con.Open();

            using (SQLiteCommand cmd = new SQLiteCommand(stm, con))
            {
                using (SQLiteDataReader rdr = cmd.ExecuteReader())
                {
                    while (rdr.Read())
                    {
                        imageData = Serialize(rdr["LastImage"]);
                    }

                    rdr.Close();

                }
            }

            con.Close();
        }
        return File(imageData, "image/png");
    }

    public static byte[] Serialize(object obj)
    {
        var binaryFormatter = new BinaryFormatter();
        var ms = new MemoryStream();
        binaryFormatter.Serialize(ms, obj);
        return ms.ToArray();
    }
}

What I'm trying to achieve with this code is to load in an image from the database into the view. Any hints as to what I'm doing wrong?

Now with RouteConfig:

public class RouteConfig
{
    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        routes.MapRoute(
            name: "Default",
            url: "{controller}/{action}/{id}",
            defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
        );
    }
}
Khaine775
  • 2,715
  • 8
  • 22
  • 51

2 Answers2

0

When you write <img src="@Url.Action("Index", "Images", new {id = item.SlideId})"/> you don't call the action but the route url. The result is a string, for example localhost:8080/images/index/abcd123456 so, if you want to call the action, you need to use @Html.Action("Index", "Images", new {id = item.SlideId}). Note @Html.Action instead of @Url.Action

Bellash
  • 7,560
  • 6
  • 53
  • 86
0

I think instead of opening and closing a db connection for each image, a better approach would be to gather all the information to render that page and send it in the model of the view you posted. Say it's called Index action of HomeController. It would look like something like this:

public class HomeController : Controller
{
    public ActionResult Index(string id)
    {
        var listOfItems = new List<SomeClass>();

        string cs = "Data Source=" + "some path";
        using (SQLiteConnection con = new SQLiteConnection(cs))
        {
            string stm = "SELECT SlideId, TimeStamp, LastImage FROM Well"; 
            con.Open();

            using (SQLiteCommand cmd = new SQLiteCommand(stm, con))
            {
                using (SQLiteDataReader rdr = cmd.ExecuteReader())
                {
                    while (rdr.Read())
                    {
                        var someItem = new SomeClass()
                        {
                            SlideId = rdr["SlideId"],
                            ImageData = Serialize(rdr["LastImage"]),
                            TimeStamp = rdr["TimeStamp"]
                        };
                        listOfItems.Add(someItem);
                    }

                    rdr.Close();
                }
            }

            con.Close();
        }

        return View(listOfItems);
    }
}

Of course if there are too many items you should always consider paging and limit the number of items in the list to cut down the response times.

Volkan Paksoy
  • 6,727
  • 5
  • 29
  • 40
  • What's your opinion on [this](http://stackoverflow.com/questions/17952514/mvc-how-to-display-a-byte-array-image-from-model) metod with adding the image as a base64 string? If I do something like you do in your answer, are there other ways to render the image than converting it to a base64 string? It doesn't work for me though since it doesn't render anything. – Khaine775 Sep 28 '15 at 14:19
  • 1
    @Khaine775: Actually if I were implementing this project I would store the images on AWS S3 and send the URL of the images instead of the data itself. That way you can use CDN's like AWS CloudFront or similar. If you're going to send the image data I think best way I know is to encode/decode in Base64 – Volkan Paksoy Sep 28 '15 at 14:22