29

I'm using ASP.net MVC C# in Visual Studio Web Dev. I have a couple of textareas which are populated with data and then updated to a database record.

Is it possible to have line breaks saved when a record is updated to the database? I currently view the data on the homepage, but at the moment if someone writes couple of paragraphs (including line breaks) the formatting will be lost.

If this isn't possible no problem, but just wanted to ask if it is. Thanks.

The code on the View page looks like this:

<div class="editor-field">
        @Html.TextAreaFor(model => model.para1, new { cols = 75, @rows = 5 })
        @Html.ValidationMessageFor(model => model.para1)
</div>

I then have a button that submits the form.

The Controller code that handles the submission looks like this:

[HttpPost]
    public ActionResult Update(Data data)
    {
        if (ModelState.IsValid)
        {
            data.ID = 1; //EF need to know which row to update in the database.
            db.Entry(data).State = EntityState.Modified;
            db.SaveChanges();
            return RedirectToAction("Index", "Home");
        }
        return View(data);
    }

and the Model code for the database looks like this:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data.Entity;
using System.ComponentModel.DataAnnotations;

namespace DFAccountancy.Models
{
    public class Data
    {
        [DataType(DataType.MultilineText)]
        public int ID { get; set; }
        public string para1 { get; set; }
        public string para2 { get; set; }
    }

    public class DataDBContext : DbContext
    {
        public DbSet<Data> Data { get; set; }
    }
}

===========================================

the Homepage code

@model IEnumerable<DFAccountancy.Models.Data>

@{
    ViewBag.Title = "Index";
}

<h2>
    DF Accountancy
</h2>
<div>

<fieldset>
<legend>About us</legend>

@foreach (data in Model)
{

<table>
    <tr>
        <td rowspan="2" width="50%">
            <b>
                Suspendisse lectus massa, feugiat at cursus ac, sollicitudin a metus.     Quisque adipiscing commodo sem vitae eleifend. 
            Maecenas ante risus, hendrerit ac tempor et, feugiat eu sapien. Sed sem massa, sodales a varius sit amet, porta in 
            turpis. Duis ullamcorper magna sed risus lobortis luctus. Quisque volutpat enim ut erat tristique sit amet posuere 
            sem ullamcorper. Nulla consequat lectus in sapien sagittis cursus. Quisque elit augue, luctus sed semper non, fringilla 
            sed quam. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Fusce vitae 
            augue quis nisi tincidunt ullamcorper. Duis posuere ultricies turpis at dictum. Vivamus at odio eros. Nunc orci 
            lectus, ornare non tincidunt sed, venenatis id lorem. Nulla ullamcorper, leo quis pellentesque sollicitudin, dui 
            libero vehicula lectus, lobortis consequat orci dui in augue. Ut gravida enim convallis sem luctus sit amet eleifend 
            lorem malesuada. Suspendisse in augue diam, eu laoreet diam.
            </b>
            </td>
            <td>
                <div class="display-field">
                    @Html.Raw(data.para1.Replace(Environment.NewLine, "<br/>"))
                </div>
            </td>
        </tr>
        <tr>    
            <td>
                <div class="display-field">
                    @Html.Raw(data.para2.Replace(Environment.NewLine, "<br/>"))
                </div>
            </td>
        </tr>
</table>
}

        </fieldset>
</div>

==========================================

The full Update View page code

@model DFAccountancy.Models.Data

@{
    ViewBag.Title = "Update";
    }



<h2>Update</h2>

<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript">    </script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>

<script type="text/javascript">
    $(function () { $("#cl_button1").click(function () { $("#para1").val(""); }); });
    $(function () { $("#cl_button2").click(function () { $("#para2").val(""); }); });
</script>

@using (Html.BeginForm()) {
@Html.ValidationSummary(true)
<fieldset>
    <legend>Data</legend>

    <div class="editor-label">
        @Html.LabelFor(model => model.para1)
    </div>
    <div class="editor-field">
        @Html.TextAreaFor(model => model.para1, new { cols = 75, @rows = 5 })
        @Html.ValidationMessageFor(model => model.para1)
        <input id="cl_button1" type="button" value="Clear Paragraph" />
    </div>

    <div class="editor-label">
        @Html.LabelFor(model => model.para2)
    </div>
    <div class="editor-field">
        @Html.TextAreaFor(model => model.para2, new { cols = 75, @rows = 5 })
        @Html.ValidationMessageFor(model => model.para2)
        <input id="cl_button2" type="button" value="Clear Paragraph" />
    </div>



    <p>
        <input type="submit" value="Update" />
        <input type="reset" value="Re-Set to begining" />
    </p>

</fieldset>
}

<div>
    @Html.ActionLink("Back to List", "Index")
</div>
JustinStolle
  • 4,182
  • 3
  • 37
  • 48
Harry
  • 735
  • 5
  • 16
  • 27
  • Can you tell if the formatting is present _in the database_ and just isn't visually represented when _displaying_ the data? – D Stanley Mar 23 '12 at 17:52
  • 1
    not sure how to check that, I've just added
     tags round the part that displays the data from the database, and that "sort" of works, however the top line of text is pushed over to the right, so it isn't quite as expected.
    – Harry Mar 23 '12 at 22:48
  • Does this answer your question? [Replace line break characters with
    in ASP.NET MVC Razor view](https://stackoverflow.com/questions/4220381/replace-line-break-characters-with-br-in-asp-net-mvc-razor-view)
    – avs099 Sep 28 '20 at 15:54

9 Answers9

45

When displaying the field as html, it will not include line breaks since they are treated as spaces in html markup. You could replace them with <br/>. It would look something like this:

<div class="display-field">
   @Html.Raw(Model.para1.Replace(Environment.NewLine, "<br/>"))
</div>

Or you could display it as preformatted text, which will preserve white space:

<div class="display-field">
    <pre>
        @Model.para1
    </pre>
</div>

Update If your model is IEnumerable<T>:

@foreach (var data in Model)
{
    <div class="display-field">
       @Html.Raw(data.para1.Replace(Environment.NewLine, "<br/>"))
    </div>
}

or

@foreach (var data in Model)
{
    <div class="display-field">
        <pre>
            @data.para1
        </pre>
    </div>
}
jrummell
  • 42,637
  • 17
  • 112
  • 171
  • 2
    I thought he was asking about _posting_ the data in the textarea. Do the linebreaks get lost? I don't think they do. Maybe I misunderstood the question. – kprobst Mar 23 '12 at 17:51
  • I don't see anything that's stripping line breaks server side, so I assumed he meant displaying the database value. – jrummell Mar 23 '12 at 17:56
  • Hi, if possible, I want the text in the textarea to keep the formatting (i.e. carriage returns or line breaks, whichever they are called) so when I display that text later on (on the homepage as it happens) it has all the line breaks that were originally entered. – Harry Mar 23 '12 at 21:22
  • Thank you jrummell, I've tried entering your example above, and it works on the update page, but when I attempt to display it on the homeepage it doesn't recognise "para1". I've added the full homepage code and update code above to see if that helps. Many thanks. – Harry Mar 23 '12 at 21:47
  • What do you mean by _it doesn't recognise "para1"_? – jrummell Mar 26 '12 at 12:21
  • Apologies, it meant it underlines "para1" in red when in Visual Studio, then when I load the site it gives an error: http://www.zen87038.zen.co.uk/image/error.jpg – Harry Mar 26 '12 at 13:38
  • Your model is an `IEnumerable` so you need to reference the current item, not the collection. – jrummell Mar 26 '12 at 13:45
  • may I ask for some assistance doing that? sorry, not got much clue :-( – Harry Mar 26 '12 at 14:02
  • Apologies for delay, I've been away and unable to test. I've got another error: "Compiler Error Message: CS0230: Type and identifier are both required in a foreach statement" – Harry Mar 30 '12 at 16:20
  • Screenie of the error is here: http://www.zen87038.zen.co.uk/dl/latest_error.jpg and I've updated the main code above to include your examples. – Harry Mar 30 '12 at 16:23
  • `@foreach (var data in Model)` – jrummell Mar 30 '12 at 17:13
  • -1 Sorry - but as an experienced user like yourself you should really not suggest using the Replace newline with
    - This can cause more issues down the line. The use of
     with those extra lines causes extra lines in the HTML - it must be 
    @content
    But that is a minor thing as using
     is the correct way to disapply pre formatted text.  Its a small issue with pre but the main concern is using the replace newline with RAW and all that. Its just not how it should be done using ASP.MVC - that is bad practice borrowed from Classic ASP. HTML or TEXT- not both at once.
    – Piotr Kula Nov 08 '13 at 16:04
  • 1
    Worse still this is a major vulnerability waiting to happen in your first example. I could insert – Tyeth Feb 28 '18 at 18:56
  • Can't please everyone :). This is a trivial example. No one should copy/paste anything from this site without fully understanding how it will impact their application. – jrummell Feb 28 '18 at 20:01
  • 1
    @jrummell : I used ur trick but it gets annoying when anyone used to type any scripts code like – Luqman Sep 27 '18 at 06:19
9

Don't manipulate the data at all. When you display it just wrap it in <pre></pre>

Example: <pre>@Model.Data</pre>

This will preserve the carriage returns

Piotr Kula
  • 9,597
  • 8
  • 59
  • 85
Kevin
  • 91
  • 1
  • 1
  • the last comment the OP made (on March 23rd) indicates that the OP already tried this. Welcome to SO, make sure you read the whole question and comments before posting an answer. (I'm guilty sometimes too) – Eonasdan Oct 11 '12 at 12:03
  • I agree with this answer! The problem is the OP is not saving the data correctly or something is causing another problem. Like stylesheet resetting (another bunch of junk) Using all these hackish fixes can cause such abnormal behavior. This deserved a +1 regardless of the problem the OP was having! It is called good codding practise! This solved my problem exactly! – Piotr Kula Nov 08 '13 at 16:11
6

Here's what I ended up doing which I think is basically the same as the <pre> tag but without the ugly bootstrap formatting (i.e. border, off white back-ground color, weird font style, etc)

CSS:

.multi-line{
   white-space: pre-wrap;
}

View:

<div class="multi-line">@Html.DisplayFor(model => model.Description)</div>
<div class="multi-line">@data.para</div>

Make sure there are no spaces between your div element and your html helper or those will show up too as someone else mentioned in the above answers with the <pre> tag.

Sum None
  • 2,164
  • 3
  • 27
  • 32
4

Pre works fine, BUT it takes some "odd" formatting.

    <pre>
        @data.para1
    </pre>

This sort of works, Except it indents the first line by the 8 spaces ahead of the @ (not right justified as it might appear at a glance)

    <pre>
@data.para1
    </pre>

This works well, but still has some stray returns.

<pre>@data.para1</pre>

This seems to be just right.

Greg Little
  • 3,360
  • 2
  • 19
  • 16
  • Excellent answer... and the font family and other formatting seems to go all wonky too. There's got to be a better way than this hurdle race down the rabbit hole. So annoying for something so fundamental. I've been looking at wysiwyg editors and the like all night when all I want are some paragraph tags and hyperlinks/img links to be visible. – Sum None Oct 25 '15 at 20:50
  • This was a classic, we had a perverted p tag with whitespace set to pre-wrap, but couldn't spot that we were using the first form in your example instead of the third form, giving us massive indentation on the first sentence only. Doh! – Tyeth Feb 28 '18 at 18:53
3

I don't know that it matters when saving the data - I assume it's just used for choosing the visualization of the member, but try moving your MultiLineText attribute to the string fields:

public class Data
{
    public int ID { get; set; }
    [DataType(DataType.MultilineText)]
    public string para1 { get; set; }
    [DataType(DataType.MultilineText)]
    public string para2 { get; set; }
}
D Stanley
  • 149,601
  • 11
  • 178
  • 240
3

The linebreak inside a textbox is CrLf so the content is not populated to a textbox the next time they will seems to disapper. However if you look into the HTML source you will find that they exist.

But because a line break isn't equal to a <br/> it will be a bit confusing.

So what people are doing is to replace the CrLf to HTML BR like this:

string ContentToDatabase = input.replace(Environment.NewLine, "<br/>")

If you open the same content in the textarea again you will see <br/> insteed of linebreaks, so you have to convert it back.

string contentToEdit = fromDatabase.replace("<br/>",Environment.NewLine)
Simon Edström
  • 6,461
  • 7
  • 32
  • 52
  • thanks for this, would you mind offering some assistance on where abouts in my code I should be adding this? I'm still very new to all this and don't understand much of it yet. – Harry Mar 23 '12 at 21:17
  • I*f I wanted to save
    to be displayed as HTML then that is how it should be saved to DB. Doing this hackish shiet is really bad codding practise! It does my head in when ppl try to solve a problem caused by a problem somewhere else.
    Is HTML and \n is NewLine - If I wanted to edit that in a separate program I would have to use this hack again. ITs baloney hacking and bad habbit. It just takes a few minutes to rethink what actually needs to happen. IOU -1
    – Piotr Kula Nov 08 '13 at 15:58
  • No, @ppumkin this is in fact the only correct answer to the OP. This will save
    to the DB. It would only need to be converted back if you OP needed it to be editable in a textarea again. Yes, it's hackish, but sometimes hacks are the only feasible solution. As far as I can tell the only other method to allow HTML editing in a textarea would be to use a 3rd party plugin such as TinyMCE, which to integrate and test takes several hours. All to allow for a couple of HTML line-breaks! That would be like using a bazooka to swat a fly.
    – clayRay Aug 28 '16 at 09:02
  • The front end should insert the br not the backend. Causing side effects isn't great. If the front end is tinymce and HTML it saves like that as it's expected. If not then no br. That is why tinymce and similar were created. To keep things consistent. – Piotr Kula Aug 28 '16 at 09:07
0
public class YourClass
{
    public int Id { get; set; }

    [DataType(DataType.MultilineText)]
    public string paragraph { get; set; }
}

@Html.TextAreaFor(m => m.paragraph, new { @class = "form-control", @rows = 5 })
Hemant Ramphul
  • 565
  • 5
  • 8
0

Your problem probably isn't in the textarea. When displaying the input back on the home page, are you doing it within pre tags? If not, line breaks and formatting are ignored.

user653649
  • 115
  • 1
  • 9
  • 1
    Hi there, thanks, no, I hadn't used pre tags, but I've since tried that and whilst it does allow for the line breaks / carriage returns it does seem to screw with the formatting a bit, including leaving the first line of text way over to the right of the div. – Harry Mar 23 '12 at 22:27
0

I have run into a similar situation with this, needing to be able to add an entire article into a database from MVC3 and text areas. There are many ways you could go about this, but the simplest I've found is to turn off the ValidateInput (do NOT do this if you are opening up this to the public...this could cause cross site scripting and all sorts of nasties, make sure you validate the users).

    [HttpPost]
    [AuthRole(Role = "Administrator")]  //Created Validataion so inaccessible from outside
    [ValidateInput(false)]      
    public ActionResult Update(Data data)       
    {       
        if (ModelState.IsValid)       
        {       
            data.ID = 1; //EF need to know which row to update in the database.       
            db.Entry(data).State = EntityState.Modified;       
            db.SaveChanges();       
            return RedirectToAction("Index", "Home");       
        }       
        return View(data);       
    }    

If you put a breakpoint in the data, you should see the newline's character ('\r\n') within VStudio. You can this replace that particular character with whatever you'd like (I'd suggest Environment.Newline if this isn't posting back to HTML).

                data.dataString = dataString.Replace(@"\r\n", Environment.Newline);
                //Or change Newline to "<br />" if posting to HTML
brenton
  • 558
  • 3
  • 18
  • Thank you Brenton. This didn't seem to work though, the AuthRole part was underlined in red in Visual Web Developer. Maybe I haven't added a "using" reference at the top that is needed? – Harry Mar 23 '12 at 22:51
  • Sorry, that's a custom attribute. You could easily just use the [Authorize] attribute. – brenton Mar 24 '12 at 00:13
  • Thank you, I've amended and it seems to like the AuthRole part now. Regarding this bit: "If you put a breakpoint in the data" where abouts should I put this? currently I've got it just above: "return RedirectToAction("Index", "Home");" - also, for some reason, when I click "update" now, it returns me to the logon page ("http://localhost:53559/Admin/LogOn") rather than back to the homepage... – Harry Mar 26 '12 at 09:21
  • This is even more shocking solution... What if I wanted to display line breaks in HTML but the actual text was used as javascript for tracking or something. Javascript does not understand
    - I need to say this because its really bad what you guys are coming up with here.
    – Piotr Kula Nov 08 '13 at 16:00