ViewStateException - Validation of viewstate MAC failed - Sitefinity ASP.NET MVC with Jquery Mobile - asp.net-mvc-4

I am getting this error most of the time when I submit my form. I am using Sitefinity 6.2 with ASP.NET MVC 4.0 and JQuery Mobile.
As I have Sitefinity in Hybred mode I am using the #Html.BeginFormSitefinity() command to create the form. On the Controller I have my action with the [HttpPost] attribute. The code always hits my default action on the controller with no problem. No matter what I put in the form when I submit I only get an error message on the page...never hits the HttpPost action.
I've looked around and there are many pages with fixes for the MAC failed issue, but none are working for me. I have a machine key in the web.config and I am NOT going to set enableViewStateMac to false as that is a security hole.

OK I tried working with both of the below solutions but they are both really bad. Here is what I am doing now, which is still not great, but I have Sitefinity, MVC, and JQuery Mobile all on the same page and forms are not giving me View State Exceptions anymore.
First thing is that adding data-ajax="false" is not enough, for this to work you need to disable Ajax before JQuery Mobile starts. So, to do this you need to add in this script BEFORE the JQuery Mobile File loads but after the JQuery file loads.
$(document).bind("mobileinit", function () { $.mobile.ajaxEnabled = false; });
After doing this I then do not use the Sitefinity Begin Form, I just JQuery to change the form on the main page to have the correct action.
<script>
$("#aspnetForm").attr("action", "Home/Login");
</script>
Together this means that there is a complete page load for each page change, and form posts use the form declared in my WebForms Master Page.
-Old Answer -
Actually...what I have below is not working. What I am
currently doing is really ugly but is usually working.
As long as the user enters the site from the home page then the home
page is the Jquery Mobile first page. The view state errors that I
was getting was because it saw the current page as the first page and
the form submit was to the active page. What if the controller for
the home page was just set to handle ALL HTTPPost calls? I have
removed the #Html.BeginFormSitefinity() from all the views with forms
and am just using the form on my top level masterpage. Then I add in
code on the view to change the action of this form to point to the
main page controller. ex
<script>
$("#aspnetForm").attr("action", "Home/Login");
</script>
Once I made this change the forms are not throwing view state
exceptions...as long as the home page is the Jquery Mobile first page.
If the user comes in from a different page then all is scrambled.
Don't have an answer for that yet.
Really Old Answer -
OK, think I have found it. I read somewhere, lost the link now, a
list of issues that can cause the error message. One of them is the
form being submitted from a different page.
I looked at the error message I was getting with Fiddler and noticed
that the Referer was my home page but the URL of the form post was the
URL for the page with my form. In stead of browsing through my site
to the page with the form I typed the URL in the address bar. I tried
submitting my form again and now it works!
So, this is an issue of Sitefinity and JQuery Mobile fighting it out.
When asp.net MVC is run in Hybred mode in Sitefinity it is actually
run in a Web.Forms master page that contains a form. When you use the
#Html.BeginFormSitefinity() to add a form to the view it is actually
just adding a div and then using AJAX to submit the form on the
Web.Forms master page.
JQuery Mobile loads up the first page that you visit, but later pages
are just injected into the existing page. So, there are multiple
data-role="page" divs loaded up in the DOM, inside of the Sitefinity
Web.Forms Master Page.
This all together is causing the form to post with the URL of the
active data-role="page" but the server sees that it is being refered
from the original page I loaded up. So, if I went to the page with
the form first all would work, start at any other page it does not
work.
Now that I know this I can put in data-ajax="false" on the link to the
page with the form and all looks to be working. This will cause
JQuery Mobile to not inject the target page into the current page but
will load all fresh with the target.
data-ajax="false" is the answer!

Related

submit button not working when generated from AJAX

I got an ASP NET Core RazorPage having a button which asynchronously replaces a part of the given HTML using an AJAX request.
Besides some text content it renders another button which is intended to post back the side when clicked. It is surrounded by a form element.
However, clicking the button I receive an HTTP 400 with the information "This page isn't working" (Chrome). Other browsers like Firefox return an HTTP 400 as well.
The relevant HTML with the button which has been created by the AJAX call is the one below:
<form method="post">
<button class="btnIcon" title="Todos" id="btnTodos" formaction="PersonManagement/Parts/MyPageName?handler=PerformTodos">Execute action</button>
</form>
As the url exists (I doublechecked it using the browser with a simple GET) I wonder whether the issue could be due to some security settings along with the browser or is there anything I am perhaps missing out here?
Thank you for any hint
Two things here first add this attribute to your form asp-antiforgery="true", then send it's value to the server in your AJAX post request.
jQuery magic starts here :)
token: $('[name=__RequestVerificationToken]').val(),
Antiforgery is ON by default since .net core 2.0 (as far as I remember), so if you do AJAX post you need to send the antiforgery token with each request.
Let us know if it helps. Spread knowledge don't hide it just for yourself :P
Finally I came across a very interesting article from Matthew Jones at https://exceptionnotfound.net/using-anti-forgery-tokens-in-asp-net-core-razor-pages/ about Anti-Forgery Tokens in Razor pages. Worth reading, indeed.
However, independently from that article what solved my issue was simply not to add the <form .. element at the client-side, but already at the server-side. As there is no need for me to explicitly adding it at the client-side, but only the button itself, this is a solution for me which works properly.
A brief summary of my scenario now:
There is a Razor Page containing usual cshtml content along with a <form method="post"..
Some anchor elements also are included, one is triggering a JQuery AJAX call to the server
The JQuery call comes back from the server with some additional HTML including the post button which which I add to the existing HTML.
The button is being rendered inside the now already existing
Clicking the button causes the page to post back in the wanted manner and executes the handler as intended.
Thanks again Stoyan for your input and help with that.

How to use/handle a loader in an MVC app?

in a ASP.NET MVC application that I am currently working there are multiple places in a single page that the user can click. So there is a main menu that's in _layout and for each inidividual page there can be links associated with that page.
I am trying to use a loader which will be shown on every click, mainly where the response takes time but for now it's for every click.
For example in the home page, from the main menu the user can click Students and the loader should come up and hide when the page loads completely. On the students page there can be an ajax call that gets data and binds it to the grid.
So from the time the user clicks on a menu link and the page loads the loader is active/shown. It's hidden once the page loads completely.
The grid can have editing functionality and when the user clicks on any of the CRUD links the loader should show and hide.
I am looking at suggestions on implementing this requirement.
If I can hookup any of the MVC events, that would be cool as I want less of Javascript/jQuery stuff but if Javascript/jQuery is the way then that's fine too.
Currently I don't have anything so anypointers are appreciated.
Assuming AJAX is being used
I don't see a way to keep this server-side without a middle page with a redirect being used (which would just be unnecessary bloat). And, since you're not opposed, you can implement this fairly easily using jQuery and something like blockUI.
I'll let you play with refining the binding to only links you care about, but for now we'll assume all links. Also, MVC should be using jQuery for things like Ajax.Actionlink so we can hijack events like $.ajaxStart and $.ajaxStop:
function showLoadingScreen(enabled){
return enabled ? $.blockUI() : $.unblockUI();
}
$(document).ajaxStart(function(){
showLoadingScreen(true);
}).ajaxStop(function(){
showLoadingScreen(false);
});
Later on you can maybe apply classes to the links you care about and just bind to them (instead of $.ajaxStart) but I'll leave that up to you.

link to another controller with hot towel and durandal

I am developing an mvc4 app with multiple spa's.
I am using the hot towel template for my spa.
What I want to do is have a anchor link within my views for a spa go to the index action for another controller, so my users can exit one spa and open another. Not all actions will start a spa some are regular mvc style pages.
I have put code like like the following in my spa html pages:
Navigate to another controller
This will change the url in the browser but always reloads the default html page for the spa. If I hit the refresh button in the browser then if will go to the proper page.
I have been able to put a target on the anchor tag of _parent or _top like:
Navigate to another controller
and it will navigate to the new controller page.
I believe it is something in the durandal framework that is preventing the spa from navigating to the second controller, but since I am just starting to work with this, I am stumped as what I need to change. I think there should be a better way than using the target in the anchor tag, or is that the best option.
I hope that I have understood you correctly. I believe this behaviour is caused my Sammy.js (which the durandal router is currently based on). The default behaviour of Sammy is to hijack all links and process them as regards to the SPA itself.
I didn't like this behaviour for the website I am working on and needed links to other MVC web pages to be possible from within the SPA. What I really wanted is for regular links to just work and hash links to be interpreted as a link to another view within the SPA. So '/controller/action' would go to another web page and '#moduleId' would go to another durandal V/VM.
I found this Sammy option that works for me and set it in my main.js
// This stops Sammy from hijacking regular links
Sammy.Application.prototype.disable_push_state = true;

How to navigate between different html pages in Windows 8 Metro application using javascript?

How can i navigate between different html pages using javascript?
I tried to use the below statement but it's not working. I have added a breakpoint and found that the below statement is executed.But still It doesn't display the page2.html.
WinJS.Navigation.navigate("page2.html", null);
Can anyone tell me why in what all scenarios it won't work ?
One option I found was iframe which I haven't tried yet.
This API isn't a specific page navigator; it's about loading the location as defined by the location service in WinJS:
http://msdn.microsoft.com/en-us/library/windows/apps/hh452768.aspx has the details on the specifics of using that model.
That stated, if you wish to use the normal Web model of a new page, either a normal link, or setting the window.location to the other page will cause a browser navigate.

WinJS Share Target Redirect

In WinJS is it possible to redirect a page once it has been activated by using the share charm?
So my target page is /pages/target/target.html. In the .js I want to do something like;
WinJS.Navigation.navigate("/pages/anotherpage/anotherpage.html");
It doesn't seem to raise an error but it's not navigating away from the target page.
I want to redirect pages based on user input.
This is similar to another question:
How to navigate between different html pages in Windows 8 Metro application using javascript?
However, if you actually are performing a page navigation (e.g. window.location changes), then you're going to have the challenge that the activation info with the share stuff will not be available; your script context is torn down on a page navigation, so you won't be able to hold onto it easily.