What's the recommended way to do client-side validation using the built-in MVC2 code with MvcContrib's FluentHtml builders? We're using the jQuery client-side validation code, not the default Microsoft AJAX stuff, if that matters (though I don't think it should).
It seems the client-side validation only gets registered with jQuery Validate when you place a validation message (Html.ValidationMessageFor(x => x.FirstName)) on the page. MvcContrib's FluentHtml this.ValidationMessage(x => x.FirstName) only works with ModelState on the server side, doesn't write out any HTML if there's no error, and doesn't register the given property with jQuery Validate on the client-side.
So my question: is there a way to make the current trunk build of MvContrib work with MVC2's built-in client-side validation somewhat painlessly right now? If so, how? If not, is there another client-side validation that's recommended (other than xVal, which we're currently using and has been depreciated)? Should this be patched in MvcContrib so it works properly? A last resort would be to move to using ASP.NET MVC's built-in input builders, but we already invested a lot in MvcContrib's and would rather not.
Thanks!
Im in the exact same situation...i came across this post with in interesting comment further down although I couldn't quite get it to work.
http://lunaverse.wordpress.com/2008/11/24/mvcfluenthtml-fluent-html-interface-for-ms-mvc/
If you can make any sense of it would be good to post it back up here.
Paul
I got the comment from that blog article working Paul, and modified it to use all the known MVC validation adapters instead of just the Required one (basically mimicking much of what's in the framework itself). It gets kind of hairy with how it displays the error message and working with what we already have, and I implemented a patch for MVC Contrib to work with it, but in the end I'm giving up for now until MVC3 is finialized and MVC Contrib builds against it. No point in going through all this when there's an updated release coming soon.
Here's what I ended up with (FluentViewPage<T> is where we add behaviors):
public class ClientsideValidationBehavior<T> : IBehavior<IMemberElement> where T : class
{
private readonly FluentViewPage<T> _viewPage;
public ClientsideValidationBehavior(FluentViewPage<T> viewPage)
{
_viewPage = viewPage;
}
public void Execute(IMemberElement element)
{
var attribute = element.GetAttribute<ValidationAttribute>();
if (attribute == null)
{
return;
}
var formContext = _viewPage.ViewContext.FormContext;
var fieldMetadata = formContext.GetValidationMetadataForField(UiNameHelper.BuildNameFrom(element.ForMember), true);
var modelMetadata = ModelMetadata.FromStringExpression(element.ForMember.Member.Name, _viewPage.ViewData);
var validators = ModelValidatorProviders.Providers.GetValidators(modelMetadata, _viewPage.ViewContext);
validators.SelectMany(v => v.GetClientValidationRules()).ForEach(fieldMetadata.ValidationRules.Add);
fieldMetadata.ValidationMessageId = element.ForMember.Member.Name + "_Label";
}
}
Hope that helps some.
Related
I would like to install ReCaptcha to our Umbraco Version 7. But I can't seem to find the correct approach. Basically I want to add the captcha element inside my custom form (not the Umbraco Form). Is there a way to do it? It seems the approach of adding the Recaptcha is not the same as how you add it in PHP application. How should I do this in Umbraco?
Update:
Recaptcha version can either be version 1, 2 or 3
reCaptcha V2 only requires a few simple lines of HTML to be inserted, AFAIK. You should be able to insert both a script tag and an HTML element anywhere inside your form element (inside Html.BeginForm if that's what you're doing) in your custom form, as long as you have an API key. I did this the other day and it just worked.
https://developers.google.com/recaptcha/docs/display
It doesn't need "installation", but it requires some fiddling with code.
I wrote a post about it here a while back, https://www.jondjones.com/learn-umbraco-cms/umbraco-7-tutorials/umbraco-security/how-to-add-a-recapture-within-your-umbraco-website/
The quick option is to install recaptha mvc via Nuget and then decorate your controller with CaptchaValidator and use the Recaptcha in your HTML
In your controller just check the form values and get the captcha value from it like this below, if that value is null then the person hasn't filled it otherwise it will have a value in it.
var formData = Request.Form;
var captchaRequest = formData["g-recaptcha-response"];
if (string.IsNullOrWhiteSpace(captchaRequest))
{
TempData["formError"] = "Fill in the Captcha box.";
return CurrentUmbracoPage();
}
Ok I found a solution with detailed explanation in this Blog
I am maintaining a customer Classic ASP website, and some ASP.NET code was found in a specific place.
I need someone to help me understand the meaning of each line, because I will have to replace this ASP.NET code with Classic ASP functions.
From my understanding, here is what the code performs :
Get the Request.QueryString url, and put it into a variable named str
Redirect (send a HTTP 302) to the Url-Decoded value of str
I would be sure not missing anything else. Is my understanding full and complete ?
Thank you all .NET folks :)
<%# WebHandler Language="C#" Class="GenericHandler1" %>
using System;
using System.Web;
public class GenericHandler1 : IHttpHandler {
public void ProcessRequest (HttpContext context) {
string str = context.Request.QueryString.Get("url");
// context.Response.Redirect( context.Server.UrlDecode(str));
HttpContext.Current.Response.Redirect(context.Server.UrlDecode(str), false);
}
public bool IsReusable {
get
{
return false;
}
}
}
Your understanding is correct. This is a simple HTTP Handler that decodes URLs and redirects the request to the decoded location.
This is not strictly required in many modern sites but it is a hack that can simplify interpreting url parameters if your site does a lot of it from first principals or in scenarios where you believe the original parameters might be double encoded.
To fully replicate the implementation, you probably don't need to replicate this code at all, not in a global sense. Instead look into the web.config or global.asax.cs or if this is more recent look for startup.cs in one of those files should be the registration for this handler, look for any references to GenericHandler1. When you find that code, you will have found the rest of the implementation detail that you may need to consider implementing.
This is a strange thing to ask, "replicate an ASP.Net website in classic ASP". I'm sure you have your business reasons, but have you instead considered upgrading to an OWIN implementation, perhaps with ASP.Net Core? This is usually the easier option if your requirement is to deploy to non IIS host.
Is there a way to manually call the XSS detection from MVC, such as from a filter, in cases when json is posted to an MVC action (like $.ajax post from JQuery with json content)?
We are using MVC 5 and have no issues with standard MVC mechanisms for catching XSS ("potentially unsafe input detected"), but a few pieces of the app use $.ajax to post JSON ("application/json" content type) to an MVC action. In these situations, we noticed the XSS detection does not run and allows dangerous form input.
In our investigation and research of similar questions here, we found JsonValueProviderFactory within the default model binder does not have same call for this XSS security that is present on form submissions or input from query string.
While it is easy to sanitize the input on client side, we obviously need a server validation as well in order to throw a 5xx (possibly something I can wrap in a filter to share across actions that could be impacted) to force this dangerous code detection on json submitted input with default model binding if possible to avoid re-inventing the wheel or inserting html encoded bad input to our db.
I found a solution that works for my situation. In this case, we had JQuery using $.ajax to post JSON to the MVC action. The default model binder does not validate posted JSON allowing unsafe XSS to be posted against our action.
To solve this, I found the RequestValidator has a static method InvokeIsValidRequestString that allowed validating a specific string to detect XSS (since every solution I had found until now reinvented the wheel here and did own XSS check for white/black list). Then it was just a matter of limiting the action to the appropriate scenario, getting the posted JSON, and throwing the validation error if XSS was detected.
public class ValidateJsonXssAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
var request = filterContext.HttpContext?.Request;
if (request != null && "application/json".Equals(request.ContentType, StringComparison.OrdinalIgnoreCase))
{
if (request.ContentLength > 0 && request.Form.Count == 0) //
{
if (request.InputStream.Position > 0)
request.InputStream.Position = 0; // InputStream has already been read once from "ProcessRequest"
using (var reader = new StreamReader(request.InputStream))
{
var postedContent = reader.ReadToEnd(); // Get posted JSON content
var isValid = RequestValidator.Current.InvokeIsValidRequestString(HttpContext.Current, postedContent,
RequestValidationSource.Form, "postedJson", out var failureIndex); // Invoke XSS validation
if (!isValid) // Not valid, so throw request validation exception
throw new HttpRequestValidationException("Potentially unsafe input detected");
}
}
}
}
}
Then, I can just decorate relevant MVC actions expecting JSON-posted data that might bypass the standard XSS prevention:
[HttpPost]
[ValidateJsonXss]
public ActionResult PublishRecord(RecordViewModel vm) { ... }
I was fortunate to stumble on thet OWASP .NET recommendations in which it recommended extending the RequestValidator object, which exposes the string validation done by the ValidateInput automatically utilized by MVC for other scenarios of query string, form collection, and cookie values.
For more info: https://www.owasp.org/index.php/ASP.NET_Request_Validation
If anyone has other recommendations, I would love to see other approaches.
I have a little problem when building my first AngularJS + C# web app. We have a plugin here (jQuery) which allow us to call a method from any input, and a little warning appears over the input field. The method works likes
user_email.warning('invalid email');
this is very simple to us. The user_email is an HTML element (input type='text') where I want to show the balloon.
But with angularJS I don't know how can I achieve this. I'm from my controller calling the web service. The webservice returns me 'invalid email/email is in use' and I need to send this warning, but inside the controller "I don't know which input is it". It's obvious I have the right name and id of field but, it sounds weird if the controller calls this method.
Can I have help about the concepts and if it's a good approach or not?
Majority of dom manipulation is done from directive. You can define a custom directive and I think that will do the trick.
//Inside directive
var ddo = { //directive definition object
scope : {
msg : '=message'
},
link : function(scope, el, attrs) {
angular.element(el).warning(scope.msg);
}
}
//In html
<input my-directive message="someVar" />
//In controller
controllerScope.someVar = /* call to your web service */
Edit: Adding blogs
http://www.codeproject.com/Articles/607873/Extending-HTML-with-AngularJS-Directives
http://blog.brunoscopelliti.com/a-directive-to-manage-file-upload-in-an-angularjs-application
Its not blog but some good directive implementations. Sometimes seeing examples and how they work helps in understanding
http://mgcrea.github.io/angular-strap/
In my MVC 3 application I am using fluent validation.
public class AccountModelValidator : AbstractValidator<AccountModel>
{
public AccountModelValidator()
{
m.NewPassword).WithMessage(Translator.Data["ConfirmPasswordValidation"]);
}
}
For localization I am using an example that I have found from here, but I have found that I have the same validation message for all languages.
The reason is that validator doesn't know that I have change the language.
How can I correctly do this?
Maybe I should use WithLocalizedMessage but it works only with .resx
When the WithLocalizedMessage returns the same value for all languages, most likely the culture isn't set yet (this happens on a POST, where the action handlers haven't run yet)
Solution is to set the culture in a different location:
Best place to set CurrentCulture for multilingual ASP.NET MVC web applications