Working example of Ajax post for Orchard?

Topics: Writing modules
Sep 18, 2011 at 6:48 PM
Edited Sep 18, 2011 at 6:52 PM

Anybody have a working example of an Ajax form post that works with Orchard's antiforgery token?

Sep 18, 2011 at 9:03 PM

There's one in the media picker.

Sep 18, 2011 at 11:34 PM

Are you referring to the - @using(Html.BeginFormAntiForgeryPost(uploadAction, FormMethod.Post, new { id = "img-uploadform", enctype = "multipart/form-data", onsubmit="jQuery.mediaPicker... from the Tab_Url.cshtml?

Can you be more specific?

Sep 18, 2011 at 11:56 PM

mediabrowser.js, line 48.

Sep 19, 2011 at 10:47 PM
Edited Sep 19, 2011 at 10:48 PM

So what keeps the View, the HTML page, from reloading after a form submit? Or does the page refresh?

Sep 19, 2011 at 10:48 PM

What do you mean? It's an ajax call: post goes in, JSON comes back. There is no reloading involved.

Sep 19, 2011 at 11:00 PM
Edited Sep 19, 2011 at 11:02 PM

I'm trying to understand.

I was using the Html.BeginFormAntiForgeryPost without giving it any argument and the page does a refresh.

@using (Html.BeginFormAntiForgeryPost())
    <div style="padding-top:20px; padding-bottom:5px;">Type message</div>
    <table style="width:100%;">
        <td style="width:80%;"><input type="text" id="MessageId" name="MessageName" /></td>
        <td style="width:20%;"><input type="submit" id="SubmitButton" value="Send" /></td>

And I don't want the page to refresh. Because I am loosing my values in my global variables. Am I missing something here?

Sep 19, 2011 at 11:04 PM

But you didn't wire up your buttons for ajax in there: your button is just a plain submit button. You may be confused about what  @using (Html.BeginFormAntiForgeryPost()) does. All it does is create a form tag that is more secure than a plain one. It does not ajax-ify your form in any way. You still need to wire up DOM events so that the ajax post is triggered when you want it to.

Sep 19, 2011 at 11:08 PM

Like onsubmit="doThis()"

If it helps for you to see what I'm doing, it is here:, Click on the Lobby tab. I took one of your vote suggestion, Chat and writing a model as an exercise. Keep in mind this is work-in-progress and only works on IE 7+. I plan to support other browsers later.

Sep 19, 2011 at 11:12 PM

Well, yes, that's one way of doing it. It's better to wire up the event unobtrusively using jQuery but that will work.

Sep 19, 2011 at 11:16 PM

Thanks, more about my progress later.

Sep 20, 2011 at 2:53 PM

I don't get why this is still reloading. Below is the code I am using. When I run the code, my action and the behavior is:

        Click on Lobby Tab - alert('New Page Loads') runs
        Type in input <return> - alert('Button Clicked') runs
                                          - alert('Form Submitted') runs
                                          - alert('New Page Loads') runs

In my form I have:

       @using (Html.BeginFormAntiForgeryPost("/WebAcre.Chat", FormMethod.Post, new { onsubmit = "doThis();" } )) {
              ... <input type="submit" id="SubmitButton" value="Send" /> ...

In my script I have: 

       alert('New Page loads.');

       function doThis() {
               alert('Form submitted.');

       $("#SubmitButton").click(function () {
              alert('Button clicked.');

I have uploaded this to my server if you need to see this.

Sep 20, 2011 at 6:03 PM

Digital and Milo suggested:

      function doThis() {
            alert('Form submitted.'); return false;

     $("#SubmitButton").click(function () {
           alert('Button clicked.'); return false;

Let me try that, I think it is working.

Sep 22, 2011 at 11:16 PM

I swear, javascript is as bad/criptic as writing Sendmail rules that's why I don't work on Sendmail, this is a variable from jquery:

    var r20 = /%20/g,
        rbracket = /\[\]$/,
        rCRLF = /\r?\n/g,
        rhash = /#.*$/,
        rheaders = /^(.*?):[ \t]*([^\r\n]*)\r?$/mg, // IE leaves an \r character at EOL
        rinput = /^(?:color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,
        // #7653, #8125, #8152: local protocol detection
        rlocalProtocol = /^(?:about|app|app\-storage|.+\-extension|file|widget):$/,
        rnoContent = /^(?:GET|HEAD)$/,
        rprotocol = /^\/\//,
        rquery = /\?/,
        rscript = /<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,
        rselectTextarea = /^(?:select|textarea)/i,
        rspacesAjax = /\s+/,
        rts = /([?&])_=[^&]*/,
        rurl = /^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,



Sep 22, 2011 at 11:24 PM

JavaScript has little to do with this. It's regular expressions that are making this hard to read.

Sep 22, 2011 at 11:26 PM

Believe me I have had my share of regular expressions, I came from the UNIX world writing shellscripts. I rather write hexadecimal code.

Sep 23, 2011 at 11:26 PM
Edited Sep 23, 2011 at 11:34 PM

Pardon my frustration and my regular expression, but getting the Orchard Antiforgery token to work is a (sed s/#$@%!/bitch/g)! Where sed is stream edit and the input is #$@%! and the output is "very hard". If I disable Orchard Antiforgery, my chat works. But if I enable it I cannot get Orchard to recognize the token. Granted this is not a big deal with a public chat, I would still like to learn how to use it and make it work.

I studied the Media Picker example and I cannot figure out what the author did to make it work. Any help?


Sep 23, 2011 at 11:38 PM

Can you show what you have so far?

Sep 23, 2011 at 11:54 PM
bertrandleroy wrote:

Can you show what you have so far?

Let me back track to a starting point and go from there.

In my script I have:

   $("#SubmitButton").click(function () {
       var UrlString = '/WebAcre.Chat/Home/Index?path=&Message=' + WebAcre_ChatTextBox.value
           + '&__RequestVerificationToken=' + WebAcre_Token
           + '&Timestamp=' + WebAcre_ServerTimestamp;

       HttpPost(UrlString, document.getElementById("DisplayId"));
       WebAcre_ChatTextBox.value = '';
       return false; // return false is needed for Orchard

In my form I have:

   @using (Html.BeginFormAntiForgeryPost("/WebAcre.Chat/Home/Index", FormMethod.Post, new { } ))
       <div style="padding-top:20px; padding-bottom:5px;">Type message</div>
       <table style="width:100%;">
           <td style="width:80%;"><input type="text" id="Message" name="Message" /></td>
           <td style="width:20%;"><input type="submit" id="SubmitButton" value="Send" /></td>

When I log in as a user and type into chat:

    validator.OnAuthorization(filterContext); throws and exception either no token or invalid token.

Additionally when I look at filtercontext in the throwned exception, within my form keys I do not show __RequestAntiForgeryToken. I must not be sending it back correctly.

Sep 24, 2011 at 12:08 AM

Side not: you might want to do some encoding on that textbox value before you inject it into the url string. Same thing for the token. See, the way the media picker script does it, it doesn't have this problem because it lets jQuery do the right thing, rather than build a URL with string concat (which is always suspect and which should be avoided if possible). Instead of putting things on the query string, I would make everything a post field, like in the media picker code. It will be so much easier.

You'll also want to make sure you have a machine key set-up in web.config.

Sep 24, 2011 at 12:17 AM
Edited Sep 24, 2011 at 12:25 AM

Unfortunately I did not understand what you said, I need examples or documentation. Shouldn't how to use Orchard Antiforgery Token be documented?

Sep 24, 2011 at 12:22 AM

It certainly should, as well as about a hundred other topics.

You are building a url by concatenating strings. Don't do that. Instead, just call the $.post API from jQuery. Look at MediaBrowser.js line 48 and do what it's doing, just substituting your message parameter to the ones that the media picker uses.

Sep 24, 2011 at 12:25 AM

Let me try that.

Sep 25, 2011 at 8:05 PM

Ok, I think I figured out how the Orchard Antiforgery token works. So now if I log in it will post. But now I need to make it post when I am logged out. It is just the opposite as before. I don't understand why this need to be so complicated. The default MVC just require a tag before the controller.

Sep 30, 2011 at 4:20 PM

Not sure if this helps at all, but I have a couple of pages where I just do a JQuery ajax post in JavaScript. I declare the Orchard AntiForgery token at the top of the page using

Then the JavaScript for the ajax post goes inside a 
@using (Script.Foot()){<script type="text/javascript"></script>}


                    type: "POST",
                    url: "/Setup/_optionInsert",
                    data: {
                        report: @Convert.ToString(Model.Report.Id),
                        option: nodeValue,
                        parent: parentValue,
                        __RequestVerificationToken: $("input[name=__RequestVerificationToken]").val()
                    success: function (result) {
                    error: function (req, status, error) {

The Setup controller as the following action because mine updates a Telerik MVC Grid

        public ActionResult _optionInsert(string report, string option, string parent)
            _setupService.CreateOption(report, option, parent);
            return View(new GridModel<ReportConfigHelper>
                Data = _setupService.GetConfigs(int.Parse(report))

but it's just as easy to send back a JSON response...I'm doing that on another site. CreateOption() and GetConfigs() are methods that are setup in my Service code.

Not sure if that helps at all.