3

I have been googlin' for a long while and have not quite found what I need. This is our scenario.

We have an MVC4 app with Razor. On one screen we are using the Telerik Editor control to save text and images. These are formatted as HTML and stored in the database. The images are stored as byte[] data and the html src "path" is updated with the distinct file name.

Later a user comes and wants to view the data. Because any images are stored in the database, I thought I could use the example found here Convert Byte Array to image and display in Razor View and I would update the tag in the HTML with the tag with a Url.Action and then render all that HTML to the screen.

A sample of my dynamically generated html code after the image tag is replaced is

<p>testing the image blah</p><p><img src="@Url.Action("getImg", "Responses", new { id = 1 }) " alt="Response Image" /> </p>

BUT If I use HTML.Raw(Text), it does not process the image. If I just copy that image tag right into the view, works great.

My question is, how can I render dynamically created HTML with Razor syntax code on a View properly?

*************** more details ***********

A few more details to help clarify what I'm doing. I have two models Response and ResponseImages.

public class Response : TrackableBase 
{
    [Key]
    public int ResponseId { get; set; }
    public string Subject{ get; set; }
    
    [MaxLength]
    public string Text { get; set; }
    
    public virtual ICollection<ResponseImage> ResponseImages { get; set; }
}

public class ResponseImage : TrackableBase
{
    [Key]
    public int ResponseImageId { get; set; }
    
    public int ResponseId { get; set; }
    [ForeignKey("ResponseId")]
    public virtual Response Response { get; set; }
    
    public string FilePath { get; set; }
    public string FileName { get; set; }
    public string FileExtension { get; set; }
    public byte[] Image {get; set;}
}

Response.Text stores HTML from the Telerik editor. I use HTMLAgilitypack to loop through all images in the HTML and from these I create the ResponseImage records, with the ResponseImage.FilePath being what I use as the link back to the HTML code stored in Response.Text (all images are updated with a distinct name/path).

On my Details.cshtml screen I want to view the details of the Response.Text. From the database my Response.Text looks like this:

<p>hjjk</p><p>
<img alt="" height="144" src="/Content/Editor_Images/UserFiles/JKULBIDA/Images/Koala_635019802303066655.jpg" width="164"></p>

BUT, because I am storing images in the database and not the file system, I again use HTMLAgility pack and update all of the image tags with the Razor syntax for using @Url.Action. My new HTML looks like this

<p>hjjk</p><p><img src="@Url.Action("getImg", "Responses", new { id = 4 }) " alt="Response Image" /> </p>

FINALLY, on my View, I want to display my data, but also have the HTML formatted properly. So I call @Html.Raw(Model.Text) and my image tag doesn't work :(

***** end of update ****

Thanks in advance, as I'm super stuck on this.

0

1 Answer 1

1

Not sure how you're storing your data, but assuming you have the ID and the text in your data, rather than building a string with the Razor syntax in it, your view should contain all the necessary markup, using variables with the data in it.

For example, if you had a partial view where your model was the image with properties Id and Description, your partial view would look like:

<img src="@Url.Action("getImg", "Responses", new { id = Model.ID })"
    alt="@Model.Description">

Then when you pass in your object into the partial, it will render normally, without any funky parsing of Razor HTML.

EDIT

If I understand your edit, you are running some code to transform the src attribute of your img tag into what you want it to be. You are transforming it into a Razor string though, not to valid HTML - what you want to do is to actually build the image's URL when you're assigning the src, rather than later on when you're in the view.

To do that, I believe this will get you going:

string imageUrl = RouteTable.Routes.GetVirtualPath(
    System.Web.HttpContext.Current.Request.RequestContext,
    new RouteValueDictionary(new { 
        controller = "Responses", 
        action = "getImg",
        id = Model.ID
    })).VirtualPath;

What this will do is build the MVC URL based on those parameters inside your code, so you can dump that straight into the src attribute. You may have to tweak this a bit if you're dealing with weird routing or anything like that - but I think it should work for a basic setup.

If you're inside of a controller, I believe you can do ControllerContext.RequestContext or possibly even just ControllerContext instead of getting the static current one.

Sign up to request clarification or add additional context in comments.

4 Comments

Thanks for the reply. I added some more info on my entire process. I'm just wondering, even thought you are suggesting to use a partial view to render my image tag, would I not still have the same problem trying to call the @Html.Partial from inside of the HTML.Raw? Or is there ultimately a better way to render the HTML/Razor mix bag?
The partial view was just so you could have the image object as a model, but you could do the same thing with a property or variable in your main view. I don't know how the HTMLAgility thing works, so I can't help there - but based on what you're doing, you're passing a string into Html.Raw, so even though it looks like Razor, it's being treated as regular text, and not executing. See my edit - now that I see what you're doing, I might have a better answer.
Of course, this makes sense now :) Tried it out, works like a charm and by only replacing the src values instead of the entire img tag, I can preserve any formatting and resizing that is done to the HTML. Gold! I'm still new to MVC so Routing wasn't even on my radar, but it is now :) Thanks soooo much!
Cool, glad it worked out. There's all kinds of awesome stuff you can do with ASP.NET MVC - I try to keep it simple whenever possible, but once in a while, there's the need to do something crazy, and there's always an answer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.