MVC receive post from another website - Chrome says Post Cancelled - asp.net-mvc

I am posting via a plain html text file on c:\ drive into my mvc website running on my machine:
<body>
<a id="testPost" href="./post_files/post.htm">test post</a>
<script type="text/javascript">
$("#testPost").click(function () {
$.post("http://hml.backend/Helix/Authorisation",
{
ClientIP: "192.168.20.34"
}, function (resultData) {
alert(resultData);
});
return false;
});
the controller is setup thus:
[HttpPost]
public ActionResult Authorisation(string ClientIP)
{
string result = _videoSecurityService.CheckHelixAuthorisation(ClientIP);
return Content(result);
}
The controller event gets hit in debug and there is no exception but Chrome says
'POST: Cancelled' in the debug window
Any ideas why?

This is a cross domain call and is not allowed in a lot of browsers, since it's a possible security risk. You could try to redirect your call on the server-side. (make the call to your own application and handle the request-response to the other website there)

Related

Asp.Net Core Unobtrusive Ajax throwing 400 error on live server

My Every form is of type
<form id="addform" asp-area="Admin" asp-controller="Departments" asp-action="Add" data-ajax="true" data-ajax-method="post" data-ajax-success="onSuccess" data-ajax-failure="onFailure" data-ajax-begin="onBegin">
</form>
I have also appended RequestVerificationToken on every ajaxSend request
$(document).ajaxSend(function (e, xhr, options) {
debugger;
if (options.type.toUpperCase() == "POST") {
var token = $("input[name='__RequestVerificationToken']").val();
xhr.setRequestHeader("__RequestVerificationToken", token);
}
});
My controllers are like this
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Add(DepartmentViewModel departmentViewModel)
{
return View();
}
Now, it is working fine locally but not working correctly on the live server.
Some requests are working fine and after few request it return 400 bad request error.
I have tried many things but all in vain. I need this security otherwise I would have skipped the same
The header name should be RequestVerificationToken without the leading underscores. The version with the underscores is the name you should use if you are posting it as a form value. You can configure this to something else:
https://www.learnrazorpages.com/security/request-verification#configuration

How to provide real time data in Asp Net Mvc that is consuming Asp Net Web Api using HttpClient?

I am developing an Asp Net Mvc client that is consuming Asp Net Web Api. For some reasons I decided to use System.Net.Http.HttpClient class, instead of jQuery AJAX to send data and get it back from the web api. So the outline of my application flow is this - an mvc controller, by using some service that wraps HttpClient within, gets the model from the web api, and then this model is passed to a View and gets displayed. The problem I am facing now is how can I provide real time data on my views using this approach? If I was using AJAX, I could make some asynchronous calls with some intervals to the web api server directly from a View and without reloading the page display the changes. Can I do it somehow using HttpClient? If not, what are some other alternatives that will align with the approach I chose to communicate with the web api?
Take a look at the simplified code I wrote to better describe my issue:
This is the controller:
public class UsersController : Controller
{
private readonly IUserHttpService _userHttpService;
public UsersController(IUserHttpService userHttpService)
{
_userHttpService = userHttpService;
}
public async Task<ActionResult> Index(int userId)
{
try
{
User user = await _userHttpService.GetUserById(userId);
return View(user);
}
//some simplified exception handling
catch (Exception)
{
return View("UnexpectedError");
}
}
}
This is UserHttpService:
public class UserHttpService : IUserHttpService
{
private const string _baseUri = "http://localhost/rs-webapi/api/users/";
public async Task<User> GetUserById(int userId)
{
string requestUri = $"{_baseUri}getuserbyid?userId={userId}";
//Here using HttpClient I fetch the data from web api
//(and I know that it's better to have one HttpClient for the whole app,
//it's just for the sake of simplicity)
using (HttpClient httpClient = new HttpClient())
{
HttpResponseMessage response = await httpClient.GetAsync(requestUri);
if (response.IsSuccessStatusCode)
{
return await response.Content.ReadAsAsync<User>();
}
else
{
throw new System.Exception("Something went wrong");
}
}
}
}
And this is the View:
#model Entities.Entities.UserBase
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Index</title>
</head>
<body>
<p>First name: #Model.FirstName, Last name: #Model.LastName</p>
</body>
</html>
Now if the user first name or last name changes, I would like to be able to display it without reloading the page. What are my options?
Now if the user first name or last name changes, I would like to be able to display it without reloading the page. What are my options?
You can completely ignore the WebAPI part of your question here. This scenario is the same as any other MVC website - how do I communicate changes in data to the browser?
And the answers are the same:
Use AJAX.
Use SignalR.
You either have to poll from your browser to your MVC app (i.e., AJAX), or you have to keep an open connection and have the server push updates (e.g., SignalR).

MVC : How to clear session and close the current browser tab on click of logout link?

I am trying to clear the session and the close the browser tab on logout link click. Please help me to do this.
Thanks in advance
You're trying to achieve two different things, one of which is a server-side concern, the other a client-side concern.
You could try splitting up these concerns, for example:
A: Using some Post/Redirect/Get laced with tab-closing javascript
Post to Logout controller method
Redirect to /LogoutSuccess
Put some javascript that closes the browser tab on body load, in the LogoutSuccess view.
B: A more client-side approach
Perform (in your javascript) a http GET to /Logout
Upon 200 OK response, execute some javascript that closes the browser tab.
Session.Abandon();
or
Session.Clean();
or
Session[".."]=null;
close windows you can use js
windows.close();
in some browser,it will pop a confirm
You can send an ajax request to to an action method which clears the session variables and in the call back, you can close the window.
<a id=logoutLink">Logout</a>
<script type="text/javascript">
$(function(){
$("#logoutLink").click(function(e){
e.preventDefault();
$.post("#Url.Action("Logout","User")",function(res){
if(res.status==="done")
{
//close the window now.
window.close();
}
});
});
});
</script>
Now in your UserController, Add the Logout action method
public class UserController : Controller
{
[HttpPost]
public ActionResult Logout()
{
Session.Abandon();
return Json(new { status="done"});
}
}
Reference:
MVC for clossing browser tab when logout
This code is from MSDN. I have added the async : false to the jQuery call as that is the key to ensure that the call flushes the Server Side session and then the window closes.
<script type="text/javascript">
$(document).ready(function () {
window.addEventListener('beforeunload',recordeCloseTime);
});
function recordeCloseTime() {
$.ajax({
type: "POST",
async: false,
url: "ServiceToClearSession.asmx/RecordCloseTime",
});
}
</script>

How to get OAuth working on MVC4 mobile

I have been struggling to get OAuth to work on my MVC4 mobile application.
I basically
Created an MVC4 Mobile application
Created an MVC4 Web application
Copied the AccountController, AccountModel, InitializeSimpleMembershipAttribute and all account views into my MVC4 Mobile application
Enabled Google and Facebook OAuth providers
I also ensured RoleManager was initialized according to simplemembershipprovider-not-working, although I do not think that was important. ( I needed it for some role-based security I was testing)
Disabled ajax ( I think) by setting data-ajax="false":
using (Html.BeginForm("ExternalLogin", "Account",new RouteValueDictionary { { "ReturnUrl", ViewBag.ReturnUrl } }, FormMethod.Post, new Dictionary<string, object> { { "data-ajax", false } })) (This did not seem to have any effect on the page - so I may be doing something wrong here...)
I can get to the LogIn view /Account/Login, and when I click the google button, the debugger breaks into public ActionResult ExternalLogin(string provider, string returnUrl)
However - the public ActionResult ExternalLoginCallback(string returnUrl) is never hit.
Visually, I get the jquery mobile "page loading" animation - then I get "Error Loading Page"
I have two questions:
How can I get more information when I try to figure out what happens?
How can I get OAuth working on my MVC4 mobile site?
BTW: Both sites target .Net4.0
OK - so I figured out the answer - the cuplrit was indeed the ajax in jQuery mobile.
I modified my _layout.cshtml so that it can render a custom script after loading jQuery, but before loading jQuery mobile:
#Scripts.Render("~/bundles/jquery","~/scripts/RemoveHashFromWindowLocation")
#RenderSection("beforeJqueryMobile", required: false);
#Scripts.Render( "~/bundles/jquerymobile")
#RenderSection("scripts", required: false)
Then I modified my Login.cshtml so that it contains the section:
#section BeforeJqueryMobile {
#Scripts.Render("~/scripts/disable-ajax.js")
}
And finally, I added the following to my scripts folder:
disable-ajax.js:
$(document).bind("mobileinit", function () {
$.mobile.ajaxEnabled = false;
});
RemoveHashFromWindowLocation.js: (Thanks to Facebook Oauth Login With Jquery Mobile #_=_)
if (window.location.hash == "#_=_")
window.location.hash = "";
Voila - OAuth working with jQuery mobile. :-)
The above answer from espenalb does work if your site loads directly to the login page, however if you have say a home page and then and a link to the login page(which uses the same layout), you will get an error loading page when you click one of the social login buttons.
To fix this add
<script>
$('#login-link').live("click", function () {
$.mobile.ajaxEnabled = false;
});
</script>
to the bottom of your mobile layout page, this will attach an event handler that will disable ajax to the login link.

using SignalR with document onload instead of jquery onload

I have used the signalR chat app (as laid out in this tutorial http://sergiotapia.com/2011/09/signalr-with-mvc3-chat-app-build-asynchronous-real-time-persistant-connection-websites/) in a standalone test site and it all works great.
I'm now trying to incorporate it into my larger project.
Now unfortunately my larger project has a body onload function defined, so i don't use the standard jquery $(function () {}); syntax for executing stuff on page load. This hasn't been too much of an issue so far, most jquery plugins and scripts get executed in the function called by my body onload and its fine.
But for some reason, my signalR code just isn't executing.
Its the exact same code as laid out above, only its called on my body load.
The page loads, does a post to /signalr/negotiate (which returns the url and clientID)
In my sample app which works, it then does a continuous post to /signalr/connect
In my other app, it simply does a single get to the page im currently on.
Its not making the post to connect.
Is there a way to manually call this?
Here is the source of the page not working.
Please note that the reason im not referencing JQuery itself is because its loaded in my master page. JQuery is present.
<script src="/public/javascript/jquery.signalR.min.js">
<script src="/public/javascript/json2.js">
<script type="text/javascript" src="/signalr/hubs">
<div>
<input type="text" id="msg" />
<input type="button" id="broadcast" />
<ul id="messages"></ul>
</div>
<script type="text/javascript">
function ExecuteOnLoad() {
// Proxy created on the fly
var chat = $.connection.chat;
// Declare a function on the chat hub so the server can invoke it
chat.addMessage = function (message) {
$('#messages').append('<li>' + message + '</li>');
};
$("#broadcast").click(function () {
// Call the chat method on the server
chat.send($('#msg').val());
});
// Start the connection
$.connection.hub.start();
}
</script>
EDIT : here is the chat hub
public class Chat : SignalR.Hubs.Hub
{
public void Send(string message)
{
//Call the addMessage method on all clients.
Clients.addMessage(message);
}
}
DOUBLE EDIT : ok, i've made a standard html page in my mvc project and wired up the onload event again and everything works fine. the problem seems to be that polling doesn't seem to working when i call
$.connection.hub.start();
instead its doing a get to the current url and returning the page again in the get request.
The problem had nothing to do with the question I asked.
I thought it might have to do with the onload function, but it did not.
The problem was because my page had a reference to the Jquery.Validate plugin.
The version I was using was 1.7, I updated to 1.9 of the plugin and it worked fine.

Resources