60

I am using Razor in my MVC3 project. And also I'm using FullCalendar JQuery plugin. So when I'm trying to fill the array it works good. Except one thing. If s.Name contains apostrophe it renders like' that's not what I want. I tried to use different methods like Encode and Decode and even MvcHtmlString.Create and result is always the same.

Here is the code snippet:

<head>
    <script type='text/javascript'>
       $(document).ready(function () {        
        $('#calendar').fullCalendar({
            header: {
                left: '',
                center: 'title',
                right: 'month,agendaWeek,agendaDay'
            },
            month: 5,
            year: 2011,
            editable: false,
            events: [
            @foreach (var s in ViewBag.Sessions)
            {
                @:{
                @: title: '@s.Name',
                @: start: new Date(@s.Starts.Year, @s.Starts.Month-1, @s.Starts.Day),
                @: end: new Date(@s.Ends.Year, @s.Ends.Month-1, @s.Ends.Day)
                @:},
            }
                   ]
        });
    });
</script>

iLemming
  • 34,477
  • 60
  • 195
  • 309

5 Answers5

116

I would write your foreach like this:

            @foreach (var s in ViewBag.Sessions)
            { 
                <text>
                {
                 title: '@HttpUtility.JavaScriptStringEncode(s.Name)',
                 start: new Date(@s.Starts.Year, @s.Starts.Month-1, @s.Starts.Day),
                 end: new Date(@s.Ends.Year, @s.Ends.Month-1, @s.Ends.Day)
                },
                </text>
            }
  • HttpUtility.JavaScriptStringEncode to escape quotes and html markup.
  • <text> is nicer for multiline output.
GvS
  • 52,015
  • 16
  • 101
  • 139
86

Here is how to do it:

title: '@Html.Raw(HttpUtility.JavaScriptStringEncode(s.Name))'
Fabrice
  • 3,094
  • 3
  • 28
  • 31
5

Try like this:

$(function () {        
    $('#calendar').fullCalendar({
        header: {
            left: '',
            center: 'title',
            right: 'month,agendaWeek,agendaDay'
        },
        month: 5,
        year: 2011,
        editable: false,
        events: @Html.Raw(new JavaScriptSerializer().Serialize(ViewBag.Sessions))
    });
});

ViewBag.Sessions might require some modifications to achieve the desired result (in terms of property names), which brings me to the usual remark I make about ViewBag when I see someone using it: using ViewBag is bad practice and I would recommend you using a strongly typed view with a view model.

Darin Dimitrov
  • 1,023,142
  • 271
  • 3,287
  • 2,928
  • Wow...wow... wow... that's interesting... could you please tell me how the structure (ViewBag.Session) should look? I'm no so good with javascript yet and I'm not sure how the similar structure would be look like in c# . Sorry – iLemming Mar 07 '11 at 23:03
  • @Agzam, I strongly suggested you not to use `ViewBag` in your controller action. But if you insist `ViewBag.Sessions` should be an `IEnumerable` where `T` is a class with properties: `Title`, `Start` and `End`. For example: `ViewBag.Sessions = new[] { new { Title: 'foo', Start: DateTime.Now, End: DateTime.Now.AddHours(5) } };` – Darin Dimitrov Mar 07 '11 at 23:08
  • This will fail if the string contains '' :( – Danny Tuppeny Jun 02 '15 at 14:09
  • @DannyTuppeny, how to reproduce your issue? The following works fine: "; } alert('@Html.Raw(HttpUtility.JavaScriptStringEncode(text))'); – Fabrice Aug 06 '15 at 15:32
  • @Fabrice It didn't when I tried it; as the browser interpreted the tag in the string as the end of the script tag (eg. [see here](http://stackoverflow.com/q/12331531/25124)). What browser did you test it in? – Danny Tuppeny Aug 06 '15 at 16:22
  • I don't remember. This is too bad. I would have thought this bug had been fixed since 2012. – Fabrice Aug 08 '15 at 13:24
4

HttpUtility.JavaScriptStringEncode is not really required here. Simply

 '@Html.Raw(s.Name)'

is worked for me.

Vijai Sebastian
  • 109
  • 1
  • 4
1

You said you already tried MvcHtmlString.Create, but for me, this seems to work correctly for me:

'Trying @MvcHtmlString.Create("Testing'`")'

.

Update:

I took your code &#39;, put it in browser, copied what showed in there, put it back in Visual Studio, like:

@MvcHtmlString.Create("'")

And it did work, I only got ' back, not &#39;.

.

Update 2:

This also works:

@{ViewBag.Symbol = "'";}
@MvcHtmlString.Create(ViewBag.Symbol)
Meligy
  • 35,654
  • 11
  • 85
  • 109
  • changed this: @: title: '@s.Name', into this: @: title: '@MvcHtmlString.Create(@s.Name)', ..... Didn't work. Renders nothing to the screen – iLemming Mar 07 '11 at 22:19
  • but if I put something '@MvcHtmlString.Create("some string with a quote ' ")' - it works. – iLemming Mar 07 '11 at 22:21
  • What is the encoding of the page and of the actual string in 1s.Name`? Maybe this is the problem? Try to make sure in your browser you view the page in UTF-8 or so maybe? – Meligy Mar 07 '11 at 22:22
  • so, somehow Razor doesn't wanna get this: @MvcHtmlString.Create(@s.Name). Why? – iLemming Mar 07 '11 at 22:22
  • I think it is specific to your s.Name string and some culture or so you may have or the name might be encoded in. – Meligy Mar 07 '11 at 22:23
  • Try with @MvcHtmlString.Create(s.Name) i.e. without the '@' – willvv Mar 07 '11 at 22:23
  • BTW, `@MvcHtmlString.Create(@s.Name)` is wrong, it should be `@MvcHtmlString.Create(s.Name)` – Meligy Mar 07 '11 at 22:24
  • LOL, you said it the same time, @willvv :D – Meligy Mar 07 '11 at 22:25
  • My biggest bet is on the extra `@` now. willvv seems to agree, and it actually makes sense, @Agzam, please try and tell us if it works :) – Meligy Mar 07 '11 at 22:27