Create a custom 'services check box item' class (reusable), and make a list or enumerable of them as a property in your AdditionalServicesModel.
Also, its probably a better idea to create a constructor of the model so you don't have to assign the model properties inside the controller.
public class ServicesItem
{
public bool Selected { get; set; }
public string Value { get; set; }
public string Text { get; set; }
}
public class AdditionalServicesModel
{
public AdditionalServicesModel(IList<ServicesItem> items){
this.AdditionalServices = items;
}
public IList<ServicesItem> AdditionalServices { get; set; }
}
Create a custom editor template for Additional Services, to easily reference in your view (you don't have to add a hidden for the text, as only the value and selected properties will be default binded back to the model:
@Html.CheckBoxFor(m => Selected)
@Html.LabelFor(m => Text)
@Html.HiddenFor(m => Value)
Then pop the editor template into your view (let MVC.net do its magic - have a look at the markup to see what it does):
@Html.EditorFor(m => m.AdditionalServices)
Then inspect the automatically bound values in your controller:
public class HomeController : Controller
{
public ActionResult Index()
{
List<SelectListItem> services = new List<SelectListItem>();
services.Add(new SelectListItem { Text = "service-1", Value = "1", Selected=false });
services.Add(new SelectListItem { Text = "service-2", Value = "2", Selected=false });
services.Add(new SelectListItem { Text = "service-3", Value = "3", Selected=false });
return View(new AdditionalServicesModel(services));
}
[HttpPost]
public ActionResult Index(AdditionalServicesModel result)
{
var selectedServicesList = result.AdditionalServices.Where(s => s.Selected);
return RedirectToAction("Thanks", "Home");
}
}
Basically, the way the Selenium detection works, is that they test for predefined JavaScript variables which appear when running with Selenium. The bot detection scripts usually look anything containing word "selenium" / "webdriver" in any of the variables (on window object), and also document variables called $cdc_
and $wdc_
. Of course, all of this depends on which browser you are on. All the different browsers expose different things.
For me, I used Chrome, so, all that I had to do was to ensure that $cdc_
didn't exist anymore as a document variable, and voilĂ (download chromedriver source code, modify chromedriver and re-compile $cdc_
under different name.)
This is the function I modified in chromedriver:
File call_function.js:
function getPageCache(opt_doc) {
var doc = opt_doc || document;
//var key = '$cdc_asdjflasutopfhvcZLmcfl_';
var key = 'randomblabla_';
if (!(key in doc))
doc[key] = new Cache();
return doc[key];
}
(Note the comment. All I did I turned $cdc_
to randomblabla_
.)
Here is pseudocode which demonstrates some of the techniques that bot networks might use:
runBotDetection = function () {
var documentDetectionKeys = [
"__webdriver_evaluate",
"__selenium_evaluate",
"__webdriver_script_function",
"__webdriver_script_func",
"__webdriver_script_fn",
"__fxdriver_evaluate",
"__driver_unwrapped",
"__webdriver_unwrapped",
"__driver_evaluate",
"__selenium_unwrapped",
"__fxdriver_unwrapped",
];
var windowDetectionKeys = [
"_phantom",
"__nightmare",
"_selenium",
"callPhantom",
"callSelenium",
"_Selenium_IDE_Recorder",
];
for (const windowDetectionKey in windowDetectionKeys) {
const windowDetectionKeyValue = windowDetectionKeys[windowDetectionKey];
if (window[windowDetectionKeyValue]) {
return true;
}
};
for (const documentDetectionKey in documentDetectionKeys) {
const documentDetectionKeyValue = documentDetectionKeys[documentDetectionKey];
if (window['document'][documentDetectionKeyValue]) {
return true;
}
};
for (const documentKey in window['document']) {
if (documentKey.match(/\$[a-z]dc_/) && window['document'][documentKey]['cache_']) {
return true;
}
}
if (window['external'] && window['external'].toString() && (window['external'].toString()['indexOf']('Sequentum') != -1)) return true;
if (window['document']['documentElement']['getAttribute']('selenium')) return true;
if (window['document']['documentElement']['getAttribute']('webdriver')) return true;
if (window['document']['documentElement']['getAttribute']('driver')) return true;
return false;
};
According to user szx, it is also possible to simply open chromedriver.exe in a hex editor, and just do the replacement manually, without actually doing any compiling.
Best Answer
The Net Tab in Firebug can help you measure and find out what exactly is affecting the load time of the website. You don't even need to have access to the server to use it. YSlow Gives you very cool tips for improving the overall load and feel of a specified site. I personaly use the Net tab to identify possible load times, may it be large images, javascripts css or bad latencies. I never heard of an automated tool for doing this, AFAIK selenium helps you build integration tests which helps you ensure certain parts of the application works as expected, but I'm not sure if it can also be used as a profiling tool. I hope this helps