Iam writing code for Registration page in Jquery, when i came to using devexpress captcha in registration page, that one is not validating from jquery.so, i replacing captcha to jquery captcha. can any one help me how to write the captcha in Jquery.
Here is a nice library I use in MVC called reCAPTCHA plugin for .NET: https://code.google.com/p/recaptcha/
There is a Nuget package available for it. Nuget id: recaptcha current verion 1.0.5.0
Now to use it: in your View
Inside your view above or bellow your Submit button: You add this code:
<p>
#Html.Raw(#Html.GenerateCaptcha())
#Html.ValidationMessage("captcha")
</p>
Then in your controller action add the RecaptchaControlMvc.CaptchaValidator attribute and also add an addition bool paramater for the recapccha e.g. captchaValid
HttpPost, RecaptchaControlMvc.CaptchaValidator]
[OutputCache(NoStore = true, Duration = 0, VaryByParam = "None")]
public ActionResult Register(RegistrationViewModel model, bool captchaValid)
{
// If the bool is true The Recapcha validation was successful.
// If not then you can add a model error with the property name for the: `#Html.ValidationMessage("captcha")`
if (!isLoan && !captchaValid)
{
ModelState.AddModelError("captcha", "Verification word is incorrect. Try again.");
}
if (ModelState.IsValid)
{
// go an ddo your registration or login
}
else
{
// handle errors and other messages
}
return View(model);
}
The Library will take care of the rest.
Related
I'm fairly new to MVC, and I seem to be having a problem returning a view from JS. I'm working on a chatting site, and this code creates a new chatroom with the name you assign it. Here's my JS code:
function CreateConversation() {
var conversationName = document.getElementById("conversationName").value;
var username = document.getElementById("usernameLabel").textContent;
window.location.href = "/CreateNewChat/CreateConversation?username=" + username + "&convName=" + conversationName;
}
That should call this ActionResult method:
public IActionResult CreateConversation(string username, string convName)
{
ChatModel model = new ChatModel(username, convName);
model.Chatters.Add(username);
return RedirectToAction("Chat","Chat", model);
}
Which does, as long as I don't type any conversation name in the text box. If I check the JS code, both username and conversation name values are correctly set up, but the ActionResult method will not be hit if I fill in the conversation name.
Here's the Chat method in the ChatController:
public IActionResult Chat(ChatModel model)
{
return View(model);
}
If I don't put any conversation name in, it will come all the way to this method, but it won't work (as that field is obligatory and I need it to load the view). Any ideas? I've tried using ajax but while it will pass the conversation name along, it will get stuck at the RedirectToAction statement (will never hit the Chat method in the ChatController). I'm really lost here.
Generally, you shouldn't pass objects around like that - at best you should only pass around ViewModels to prevent someone from fudging data and potentially breaking your app.
The way you have it with your redirect will actually push the whole model into the URL parameters before stepping back into code, leaving it wide open for someone to change as they see fit.
Ideally you would post to create a persisted instance then redirect by passing only an identifier to the Chat() method like so:
CreateNewChatController.cs
public ActionResult CreateConversation(string username, string convname)
{
Guid chatId = yourServiceFactory.CreateNewChat(username, convname);
// You passed the service the username anyway so it can do the Chatters.Add() internally
return RedirectToAction("Chat", "Chat", new { id = chatId });
}
ChatController.cs
public ActionResult Chat(Guid id)
{
ChatModel model = yourServiceFactory.GetChatById(id);
return View(model);
}
However, if you really want to pass the model onto ActionResult Chat(ChatModel model), then you can execute and return the controller action directly.
public IActionResult CreateConversation(string username, string convname)
{
ChatModel model = new ChatModel(username, convname);
model.Chatters.Add(username);
ChatController chatController = new ChatController();
return chatController.Chat(model);
}
I've created a very simplistic working example of this based on what you've said above, so any validation you may have in your ChatModel constructor is omitted in my example.
For any other errors, I would suggest checking to see if the values you're passing in aren't being detected as "potentially harmful" by the app and being dropped.
Noting that the use of .textContent instead of value would get the full contents between the start and ending tags of a given element, I'm assuming the element is a textarea type not a normal text input. You could be getting extra elements between <textarea>...</textarea>
In my example, my javascript function just takes two local variables declared and set within the function. Without seeing your submit page, I can't really comment on why else setting a value would prevent a call from working.
Good day!
I'm dealing with an issue for some time now and can't seem to find a solution. I have an usual ASP.NET MVC project on 'top' of which I added an Angular JS project. I also have a Web API, but this is not relevant for my issue. The web application itself is the Angular project, making calls to the API.
I used the default authentication system from ASP.NET MVC using the default Login.cshtml View and default AcountController methods for login/logout.
The problem I'm dealing with is the following:
A user enters the website and is prompted with the login form. After inserting valid account details, he is redirected to the main page (index, from the angular js project). IF the user clicks on the Back button of the browser, he is prompted with login form again and if he inserts his user and password again (or any other sign-in details), I receive a HttpAntiForgeryException with the following message: "The provided anti-forgery token was meant for a different claims-based user than the current user."
I tried disabling the back button with javascript (window.history.forward(1);), but it doesn't work apparently on older browser versions and it's by far an elegant solution. I tried reloading the login page (because after clicking back, if you reload the page you will be redirected to the index page (since the session is still valid)) and none of these solutions really work.
Any ideas?
Thank you in advance!
Update: so far I've included AntiForgeryConfig.SuppressIdentityHeuristicChecks = true; in Application_Start() and also this:
public class HandleAntiForgeryError : ActionFilterAttribute, IExceptionFilter {
#region IExceptionFilter Members
public void OnException(ExceptionContext filterContext)
{
var exception = filterContext.Exception as HttpAntiForgeryException;
if (exception != null)
{
var routeValues = new RouteValueDictionary();
routeValues["controller"] = "Account";
routeValues["action"] = "Login";
filterContext.Result = new RedirectToRouteResult(routeValues);
filterContext.ExceptionHandled = true;
}
}
#endregion }
[HandleAntiForgeryError]
public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
{
}
The only issue left is when I click back and try to login with another user it fails. Meaning I remain logged in with the previous user. I expect this to be normal, but is there a way to change that (as in when I click back and enter other user's credentials, to get logged in with those new credentials (even though I'm already logged in)).
SOLVED: In my code I had the following line:
if (User.Identity.IsAuthenticated)
return RedirectToAction("Index", "App");
That is why after logging in with another user I was being redirected to index being logged in with the old credentials.
I had this same issue and i solved this issue by adding following line in Application_Start() event in Global.asax in my case:
AntiForgeryConfig.SuppressIdentityHeuristicChecks = true;
Also add this in Application_Error():
Exception ex = Server.GetLastError();
if (ex is HttpAntiForgeryException)
{
Response.Clear();
Server.ClearError(); //make sure you log the exception first
Response.Redirect("~/Home/Index", true);
}
I am adding authentication to my web application. It is an asp.net mvc single page application. Currently the web application is using the asp.net mvc for only one thing, authentication. I check the Request.IsAuthenticated in the AppController, if it isnt authenticated than I serve the login page (else I save the app.html page). In my AccountController I have the following Logon Action:
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public ActionResult LogOn(LogOnModel model, string returnUrl)
{
if (ModelState.IsValid)
{
//VALIDATE USER NAME AND PASSWORD
if (Repository_Security.CheckUser(model.UserName, model.Password))
{
FormsAuthentication.SetAuthCookie(model.UserName, model.RememberMe);
if (Url.IsLocalUrl(returnUrl) && returnUrl.Length > 1 && returnUrl.StartsWith("/") && !returnUrl.StartsWith("//") && !returnUrl.StartsWith("/\\\\"))
{
return Redirect(returnUrl);
}
else
{
return RedirectToAction("Index", "App");
}
}
else
{
ModelState.AddModelError("", "The user name or password provided is incorrect.");
}
}
// If we got this far, something failed, redisplay form
return View(model);
}
Really its just taking a user name and password and validating against the database. Than sets the AuthCookie if it passes.
My question is, is this possible if I do this entirely clientside in the browser in javascript and ajax data calls? Than be able to add a check in my clientside code to see if the user is authenticated, else throw them to a login page?
Any ideas? thanks.
Yes, and MVC is perfect for working clientside Ajax.
You can modify your controller to return JSON, and with a jquery ajax call you can process the returned json using clienside javascript.
Change the last line (return View(model)) to look something like the following
return Json(new {IsSuccess=successVariable, RedirectUrl=myRedirectUrl, Message=failedErrorMessage});
Adjust your Redirect lines to instead set myRedirectUrl variable.
Update
If you want to get rid of MVC in your project (as it's an overkill for such a simple task), add a web service (asmx) to your site. Inside create a webmethod similar to following:
[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public LogonResponse Logon(LogonModel model){
... do login logic as your original code...
return new LogonResponse() { IsSuccess = successVar, RedirectUrl=myRedirectUrl, Message=failedErrorMsg};
}
You can do that from client-side as well... but if your application need full security then this model will open-up many security loop holes.
When you call FormsAuthentication.SetAuthCookie() it sends a Set-Cookie header back to the client so their browser can store the authentication cookie. You can just check for the existence of this cookie client-side with JavaScript. If it exists then continue, if it doesn't then do a redirect (window.location.href) to the login page, e.g.:
if (document.cookie.indexOf(".ASPXAUTH") >= 0) alert("You are logged in");
else window.location.href = "http://www.domain.com/login";
I have a commandbutton, When click I want it to save a phonecall record and redirect to the record page, after that open a new page in a new window which shows the editing page of a new case related to the call.
I am doing it like this:
//Pseudocode
public PageReference saverecord(){
create a new phone call record;
insert record;
if(createnewcase)
create case;
insert case;
create editcaseURL;
return phonerecord page;
}
on the client side, In the commandbutton, I use <apex:param name="newcase" value="true" assignTo="{!createNewCase}"/> to set the createnewcase to true. and oncomplete javascript to open the popup window. I have test the phonerecord and caserecord seperately and succeeded. but when I put them in one class, the case was never created. and in the visualforce view state window. I can't even find the boolean createnewcase.
please help.
Thanks
It is easy to implement with Apex / JavaScript:
The apex code:
// Defining two variables for the both records (case and phone)
public String caseId { get; set; }
public String phoneId { get; set; }
// Defining a boolean to render the JavaScript panel after saving
punlic Boolean redirectNow { get; set; }
public PageReference saverecord(){
// Create a new phone call record;
insert record;
// Now reading a phone record id
phoneId = record.id;
if(createnewcase){
create case;
insert case;
// Now reading a case id
caseId = case.id;
}
// If case and phone are OK -> set this flag to true
redirectNow = true;
// We do not need to return a real page reference
// because we will redirecting with javascript
return null;
}
And the Visualforce page with JavaScript:
<!-- A command button, that rerenders a panel with JavaScript -->
<apex:commandButton value="Save" action="{!saverecord}" reRender="doAfterSave"/>
<!-- This panel renders only after you will save the new records -->
<apex:outputPanel id="doAfterSave">
<apex:outputPanel rendered="{!redirectNow}">
<script>
// First reading the id's
var newCaseId = '{!caseId}';
var newPhoneId = '{!phoneId}';
if(newCaseId != '' && newPhoneId != '')
{
// Now opening a new window with case in edit mode
window.open('/' + newCaseId + '/e');
// And then redirecting the main page to the new phone record
window.location = '/' + phoneId;
}
</script>
</apex:outputPanel>
</apex:outputPanel>
If you want to open newly created case in edit mode then use following code.
public PageReference saverecord(){
create a new phone call record;
insert record;
if(createnewcase)
{
create case;
insert case;
return new PageReference('/' + case.Id + '/e');
}
else
do other logic here
return null;
Although this article is dated, if you really need to use JavaScript and popups to get this job done (as opposed to simply using Visualforce pages and passing parameters in the url, or using VF pages that share the same controller thereby maintaining the same context, member variable values, etc.), I'd take a look at this tutorial: Tutorial: Modal Dialogs in Visualforce using the Yahoo! User Interface Library
The essential trick is to make the "popup" really just a hidden aspect of the same page to circumvent issues associated with passing around values with JavaScript in Visualforce.
From the tutorial:
Building a link or button to popup a new Visualforce page is actually
quite simple, and getting this popup to be above the current page is
also quite easy. The problem occurs when you would like to collect
information in the popup and pass that information back to the page
that launched the popup.
The issue is that the new window is launched as a separate browser
request when you use window.open(). Since this is a separate request
to the server, the new page does not share the same controller
context/session. Even if the two pages both use the name of the same
controller! This is due to the fact that these are two different
requests at the browser level.
I think question is clear. I want to handle url strings which can be added by user.
Example;
http://download.cnet.com/windows/script alert('hello') /script
or
http://download.cnet.com/windows/aaaaaaaaaaaaa
As you can see in examples, cnet handle these inputs and redirect user to custom 404 file.
I'm working on mvc3 razor, it's something with controller I suppose, but I can't make it.
Extra Information:
What I want to do; I want to handle or external string which can be added end of the url.
Another example; http://www.yazilimdevi.com/yazilimdevi/aaaaaaaaa
As you can see, if user input "aaaaaa" to end of url; he/she see "Server Error in Application" which was prepared by IIS. I want to create a custom page, and redirect all users who added unknown path, string or script...
Thanks...
If you want to implement special handling for this scenario then you may want to add new route using /{*arbitrary_url_part} scheme. For example, route
routes.MapRoute(
"SampleRoute",
"constant_path/{*variable_part}",
new {controller = "ErrorController", action = "ShowError", variable_part = ""}
);
will match all those urls:
http://Server_url/constant_path/ (variable_part=="")
http://Server_url/constant_path/aaaaaaaaaaaaa (variable_part=="aaaaaaaaaaaaa")
http://Server_url/constant_path/script alert('hello') /script (variable_part=="script alert('hello') /script")
etc. no matter how much slashes or other special symbols user puts in. For reference, see MSDN: ASP.NET Routing - Handling a Variable Number of Segments in a URL Pattern
.
If you don't want to bother yourself with implementing all this stuff and only want to show a fancy 404 page to user then you might consider using standard ASP.NET feature - Custom error pages
Other strategies on handling such requests can also be found in This blog post.
UPDATE
If you want to go the first way, you'll also have to add controller and view for displaying some custom error page. If you take the same names as in route you'll have to add following to your project:
File Controllers/ErrorController.cs containing class ErrorController with method ShowError, like this:
using System.Web.Mvc;
namespace Your_app_name_here.Controllers
{
public class ErrorController : Controller
{
public ActionResult ShowError(string variable_part)
{
return View((object)variable_part); // Cast to object is required here
}
}
}
File Views/Error/ShowError.aspx - a simple HTML view to display error information, like this:
<%# Page Title="" Language="C#" Inherits="System.Web.Mvc.ViewPage" %>
<HTML>
<HEAD><TITLE>Error page title here</TITLE></HEAD>
<BODY>
<H1>variable_part = <%=Model.ToString()%></H1>
</BODY>