This is a MVC3 project using razor. Instead of displaying another view to inform the user that the changes have been saved successfully I would like to simply fire a JavaScript popup informing them... Everything I have found on the web either opens a whole new browser window, or misses what I am trying to accomplish all together... I know there is a simpler way to go about doing this but this is where I am... At the end of the controller function that does the save on the return I simply use redirect and send it to another controller function that displays a screen saying "Changes Have Been Saved Successfully" then the user clicks a button there which will take them back to the index page... IMO this is a bit shotty and think it can be cleaned up through the use of Javascript...I have not found any luck on this yet.. Currently the below code is what I am using:
Function SomeFunctionName()
db.SaveChanges()
Return RedirectToAction(ChangesSaved)
End Function
Function ChangesSaved()
Return View()
End Function
And the javascript that I have implemented in the ChangesSaved view.
#Code
ViewData("Title") = "ChangesSaved"
End Code
<script type="text/javascript">
alert("Changes Have Been Saved Successfully");
</script>
There are a few problems with this though...
How do I tell the javascript When the user clicks OK it should take them to another page.
I did just try the below and since I am very new to java/javascript it failed:
var r=alert("Changes Have Been Saved Successfully");
if (r == true) {
#html.Action("***********","Admin")
}
If I were you I would post your form using Jquery. Then you can set a callback. In Mvc you can return JSON data, a simple value indicating that the save worked would be enough. Then you can call your alert although you might consider using a jQuery UI dialog as it's way more flexible. If you haven't ever used jQuery I wouldn't be afraid, it's easy and there is a lot of great examples out there.
Take a look at this http://api.jquery.com/jQuery.post/ and this, ASP.NET MVC controller actions that return JSON or partial html
Related
I just finished localizing my web application using spring boot configuration as a base.
#Bean
public LocaleResolver localeResolver() {
return new CookieLocaleResolver();
}
Due to a requirement one is supposed to be able to change locale/language of the website by pressing a button. Said function is implemented with a little bit of JS and a cookie.
<script>
function updateCookie(lang) {
let name = "org.springframework.web.servlet.i18n.CookieLocaleResolver.LOCALE"
document.cookie = name+"="+lang
location.reload()
}
</script>
<a onclick="updateCookie('de')" class="flag-icon flag-icon-de mr-2"></a>
The idea is to update said cookie on click of a button and use it throughout the whole application. This works fine until I am trying to call a specific endpoint in my application.
In order to debug my application I use:
window.onload = function () {
alert(document.cookie)
}
Now to my problem:
When User-Testing the application this is the alert-feedback:
org.springframework.web.servlet.i18n.CookieLocaleResolver.LOCALE=de
Switching to other pages, refreshing, changing language etc. properly resets the cookie with a different value.
When calling a specific endpoint though, I get the following alert:
org.springframework.web.servlet.i18n.CookieLocaleResolver.LOCALE=de;
org.springframework.web.servlet.i18n.CookieLocaleResolver.LOCALE=fr
Instead of resetting/changing the existing cookie, a new one is added with the value 'de;'. A seemingly random semicolon is added.
This doesn't happen with endpoints using similar logic and almost identical implementation.
There is no further logic outside the little bit of JS code I've posted and I'm not touching the cookie in the backend.
Unfortunately I'm out of ideas. Any tips/help would be appreciated.
Is there any to pass some data from HTML property on changed event data to asp.net core razor pages?
I want to get an ID from dropdown list from HTML using JS and pass it to Razor Pages (asp.net core 2) and get the result from the custom method ?
Code I want to be look like below if possible :)
JS code
$('#Neighborhood_DistrictId').on('change', function () {
#Model.GetDistrictName($('#Neighborhood_DistrictId').val());
});
On the Razor page
public string GetDistrictName(Guid id)
{
return httpSystemApi.GetByIdAsync<District>("Districts", id).Result.Name;
}
GetDistrictName method is connecting to API and returning the value. I don't want to direct connect to API with JS if there is a way to do what I want
I am playing around with Razor Pages, and I have the same issue. Below is my work around. It seems like there should be some event handler will do the same thing, but I have not found another way yet. I tried treating it like the MVC controller, but I believe there is some form token that it is expecting so that did not work [name="__RequestVerificationToken"].
Basically what I am doing here, is tricking the page into thinking I clicked a button and then telling it which function to look at. Additionally, you have access to all your model fields so you do not need to pass them.
Here is the select list:
<div class="col-md-2"><select id="ddlPortalName" asp-for="selectedPortalName" asp-items="Model.portalNames" onchange="ConcatenateURL();"></select></div>
And then here is the JS function, notice I had to change the form action to tell it which page function to look at.
<script type="text/javascript">
function ConcatenateURL() {
document.forms[0].action = "VisibilityTest?handler=ConcatURL";
document.forms[0].submit();
}
</script>
And then finally here is the c# file method.
public void OnPostConcatURL()
$('#Neighborhood_DistrictId').on('change', function () {
#Model.GetDistrictName($('#Neighborhood_DistrictId').val());
});
#Model.GetDistrictName is a server side method not Usage directly inside script
$('#Neighborhood_DistrictId').on('change', function () {
var url="http://localhost/{controllername}/{methodname}/id=";
url=url+$('#Neighborhood_DistrictId').val()
$.get(url,function(data){
...some code
});
});
var url="http://localhost/{controllername}/{methodname}/id=";
In mvc 5 genrate url from server side and set the client side variable
var url='Url.Action("{action}","{controllername}","actionname")';
this is only way for call the controller using javascript or jquery not Directly use server side method in javascript.
I am trying to find out what the safest way to store data for use when the user clicks on a button.
I know that you can store data in attributes(either the value attribute or a data- attribute) of the button tag like so:
<button type="button" value="1" data-value="1">Click me!</button>
But the problem with this is that the user(probably really only advanced users) can manipulate the value with firebug or some other app and THEN click the button and send over different data. I fully understand that I need to check the input before I try to do anything with the sent data.
I also found out that I could use jQuery's .data() to attach data to dom elements, which seems a bit more useful. I'm not exactly sure how the data is stored, but I assume its harder to manipulate.
What got me really interested in this question was when I was looking through Soundcloud's code in firebug, I saw that none of the "like" buttons had data attached to the buttons. I tried deleting/manipulating elements/data and the buttons still worked. So it got me thinking that they are probably using a similar process to what jquerys data() is doing.
I just want to know if there is a safer way to store data or a way so that the user can't manipulate the data before clicking the button.
Consider this function:
function setupPrivateData(element) {
var private = 1;
element.setPrivate = function ( d ) { private = d; }
element.getPrivate = function ( ) { return private; }
}
When called with some DOM element it will add two methods to it: .setPrivate(val) and .getPrivate().
These are the only methods that will allow you to access and modify that private variable associated with the element.
The user can always manipulate data. Nothing stops an advanced user to access object properties or call a jquery.data() on their own.
Something you could do in vanilla js would be:
var div = document.getElementById("test");
div.something = "hidden value";
div.addEventListener("click", function() {
alert(this.something);
});
<div id="test">click me</div>
The best way would to be a serverside verification if the sent data is valid or not.
Besides that, you could try to wrap your code in an anonymous function to deny the user access to the object:
(function() {
var data = {};
data.something = "test";
})()
But even that fails as soon as the user manipulates your files and adds for instance a debugger statement.
You can obfuscate your javascript but the only validation has to be done on your server. For example, I tried to get the weather from theweathernetwork. They have hidden their API call using multiple files and callbacks. In my opinion, it's just more challenging (funnier) if you want to reverse-engineer their site.
Javascript can't be secure. Never trust user input
If you are logging button clicks, the safest way to keep track is to save and validate on the server side.
For example, when you click a like button on Soundcloud, it makes an HTTP request to Soundcloud's server, records that you clicked the button, and marks it as a favorite. This way, if the same user clicks the button anytime in the future, it can check before incrementing the number of favorites.
The number displayed in the button is also pulled in from the database when the view is rendered.
This is a huge topic, and you have a lot to learn, far too much for a comment here. Anything "stored" in an attribute in the HTML source is absolutely not secure, it can be changed very very easily.
The most common way of dealing with this would be to use a cookie, but even with some effort these can be manipulated.
If security is important, find some way of identifying your users (possibly by IP, but even that isn't fool proof!) and keep the data on your server, linked to a user ID which can be retrieved after the button is clicked.
I'm using ASP.NET MVC Framework 3 and Forms Authentication. I know, how to check on servers side, if the user is authorized for some action (with [Authorize]) and I know, how to check this within an action or a view (with User.Identity.IsAuthenticated or other members of 'User').
What I'm trying to do - is to define some JavaScript code, that will be executed differently, depending if the user is authorized.
Consider such script on the page:
<script>
function Foo(){
if(userAuthorized)
alert("You\'re in the system");
} else {
alert("You\'re not authorized");
}
<script>
Function Foo() is triggered by some event, say click. And I'd like to have an ability to check, if user is authorized, on clients side.
The best solution I've came up with is to actually render global variables initialization in view. Like this:
#if(User.Identity.IsAuthenticated)
{
<script>
var userAuthorized = true;
</script>
}
else
{
<script>
var userAuthorized = false;
</script>
}
But it doesn't seems to me as a good approach. Are there any other ways?
Thanks in advance.
PS: This is a usability issue, of course I'm doing necessary checks on server.
I like the idea in #Gaby's comment, though I am not sure whether that's doable since I don't have the whole picture on your project.
At the very least you can simplify your code by doing...
<script>
var userAuthorized = #User.Identity.IsAuthenticated.ToString().ToLower();
</script>
Another couple of options would be to use a custom HTML data- attribute or create a simple ajax request that asks the server if the user is authenticated.
I just started to investigate mvc on javascript client side (JavaScript MVC). Everything looked great until I got to form submitting :) View part won't do it, that's simple. Event is attached in Controller, so Controller is good place to validate form data, but I'm not sure I want my Controller to know specific server address (were to post my form), so would be great to have a method in Model, but then I don't want my Model to know about my Form (which is actually html structure...).
Well, what do I miss about MVC conception? I am also not sure I want to serialize my form in Controller and then pass it as parameter to my Model. For now, the only option I see to make Model independent is to have JavaScript structure (entity), which will be filled by controller (based on form data) and will be passed to the Model method to be saved on server. Very smplified code:
Info = {
name,
address,
// 15 more properties
...
}
InfoController = {
...
onFormSubmit: function() {
...
info.name = document.getElementById("info-name").value;
info.adress = document.getElementById("info-address").value;
...
InfoModel.save( info );
}
}
InfoModel = {
...
save: function( info ) {
// here some code to setialize info object
// send it to server
...
}
}
But it makes my code too complicated (comparing to simple form serizlization by some side frameworks and just sending it..). What's the right choice?
Just answering my own question. Short answer - yes, I was right with my assumptions ;)
I took a look at JavaScriptMVC, and noticed one simple thing I missed, a simple function can be developed which will create javascript object based on form (they have function called formParams which performs this type of converting). This way my controller is simplified:
InfoController = {
...
onFormSubmit: function() {
...
var info = $infoForm.formParams();
InfoModel.save( info );
}
}
Now it does not look that complicated, and its advantage is that there is one place (model) which knows how to save data (validation; url to send; some other stuff like add this entity to client side 'storage'; firing an event that something new is going to be created; whatever else according to our needs), and if I have one more place, or control flow to perform this operation again I won't write this code again, and it does not depend on presentation (is it form, or just set of inputs, wizard etc.). Also Model becomes quite reusable.
Actually before using this approach we had something similar, but it was not that structured (among different presentations for my application which can run javascript).