Category Archives: javascript

Reading hidden field values with Selenium

I have a need to hide a guid used for an index on a .cshtml so I can get model binding on controls dynamically added with ajax (it’s a long story) (that was a mouthful)

I had a hard time finding the value in the hidden field; as it turns out, you can just get it by the attribute on the Selenium element like this:


IWebElement hiddenIndex = driver.FindElement(By.Id("MyControlName_0__Index"));
var indexValueToUse = hiddenIndex.GetAttribute("value");

 

Implementing reCAPTCHA in a Razor MVC view

Setup in your Google account

You will have to have a Google account to use reCAPTCHA.

Log into the google account you want to tie your reCAPTCHA keys to and navigate to:

https://www.google.com/recaptcha/admin#list

Under the ‘Register a new site’ section of that page,follow the instructions and set up a separate key set for each of your development,test, and production environments – including one specifically for ‘localhost’ or 127.0.0.1 so you can test locally.

Web config changes

Add the public and private keys you just created on the Google site to your web.config:

<add key="ReCaptchaPrivateKey" value="yourPrivateKey"/> 
<add key="ReCaptchaPublicKey" value="yourPublicKey"/>

HttpGet action in the controller

Add a property for yourPublicKey to your viewmodel and load it from the web.config in the get controller action, passing it into the view.

Changes in the head section

Add this script in the head section of your layout or view page:

<script src="https://www.google.com/recaptcha/api.js?render=@layoutModel.yourPublicKey"></script>

Changes on the .cshtml view page

There are two steps for the view page where you want to display the reCaptcha box:

Add this to the view where you want the reCaptcha box to display:

<div class="g-recaptcha" data-sitekey="@Model.YourPublicKey">

And add this script at the bottom of that view:

<script src='https://www.google.com/recaptcha/api.js'></script>

HttpPost action in the controller

You will need some code in the post action of your controller to hit the Google reCaptcha service and get a response if it appears this is a valid person – something like this:

var response = Request["g-recaptcha-response"];
var reCaptchaSecretKey = ConfigurationManager.AppSettings["yourPrivateKey"];
var webClient = new WebClient();
var resultFromGoogle = webClient.DownloadString(string.Format("https://www.google.com/recaptcha/api/siteverify?secret={0}&response={1}", reCaptchaSecretKey , response));
var parsedResponseFromGoogle = JObject.Parse(resultFromGoogle);
var thisIsARealPersonNotARobot = (bool)parsedResponseFromGoogle.SelectToken("success");

With that result in hand, you can decide how to handle a success or failure.

Gotchas:

I noticed that reCAPTCHA tried to send it’s request through TLS1.1 and our site will not allow it – we require TLS 1.2, so I had to add a directive to force it to only use 1.2 with this setting at the top of the HTTPPost controller action:

  ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

Thanks for reading and happy coding,
-Jim

Downloading a file from MVC controller to .ascx using javascript ajax

Here is a simple way to download a file to a .net user control from a newer MVC controller.

The Controller code:

public FileResult DownloadSweetFile()
{
var downloadDirectory = _appSettings.PathToFile;
var filePathAndName = Path.Combine(downloadDirectory, "MySweetFile.pdf");

var cd = new System.Net.Mime.ContentDisposition
{
FileName = "MySweetFile.pdf",
Inline = false, //NOTE: This forces always prompting the user to download, not open file in the browser
};
Response.AppendHeader("Content-Disposition", cd.ToString());

return File(filePathAndName, "application/pdf");
}

I used a button on the page to fire the javascript

button type="button" id="btnSweetDownload" onclick="downloadSweetFile();" Click here to download a Sweet File!
(I removed the button tag so this will show correctly)

And here is the javascript to use in the .ascx file:

function downloadSweetFile() {
var url = '/MyControllerName/DownloadSweetFile';
window.location = url;
};

Sending messages from an MVC Controller to toastr.js

Toastr and MVC controllers

I often want to generate a message in an .Net MVC controller class and present that to the user with toastr.
Here is a nice pattern for doing just that using TempData.

The Javascript

In a javascript file that is accessible to all the views that are using toastr:

$(document).ready(function() {
if ($('#success').val()) {
displayMessage($('#success').val(), 'success');
}
if ($('#info').val()) {
displayMessage($('#info').val(), 'info');
}
if ($('#warning').val()) {
displayMessage($('#warning').val(), 'warning');
}
if ($('#error').val()) {
displayMessage($('#error').val(), 'error');
}
});

var displayMessage = function (message, msgType) {
toastr.options = {
“closeButton”: false,
“debug”: false,
“positionClass”: “toast-top-right”,
“onClick”: null,
“showDuration”: “300”,
“hideDuration”: “1000”,
“timeOut”: “8000”,
“extendedTimeOut”: “1000”,
“showEasing”: “swing”,
“hideEasing”: “linear”,
“showMethod”: “fadeIn”,
“hideMethod”: “fadeOut”
};

toastr[msgType](message);
};

The Layout or Master Page

If you are using razor with mvc, you can put this in your _layout:

@Html.Hidden(“success”,@TempData[“success”])
@Html.Hidden(“info”,@TempData[“info”])
@Html.Hidden(“warning”,@TempData[“warning”])
@Html.Hidden(“error”,@TempData[“error”])

On my current project, I am working on an older mixed webforms and mvc site so I put this in the views:

<input type="hidden" value="<%=TempData["success"]%>" id="success" />
<input type="hidden" value="<%=TempData["info"]%>" id="info" />
<input type="hidden" value="<%=TempData["warning"]%>" id="warning" />
<input type="hidden" value="<%=TempData["error"]%>" id="error" />

The Controller Code

You send information back from the controller like this:

TempData["warn"] = "You must see this amazing information in a toast!!!";