Asp.net MVC Validating Dynamic Form - asp.net

I'm building an ASP.NET MVC application with a form that needs validation. The majority of the form is static, but part of the form is dynamic.
I need to enable the user to enter n string/date combinations.
The string/date combos need to be validated server side, and I need to give feedback to the user preferably directly beside the combination that failed validation.
For static input I do the following:
<%= Html.ValidationMessage("someField") %>
For the dynamic data, what should I do?

In your controller you'll want to assign an error to the particular fields that fail validation:
ModelState.AddModelError ("textbox1", "You must specify a valid string.");
ModelState.AddModelError ("combobox1", "You must specify a valid date.");
Then all the helper is really doing is checking if the following exists:
ViewData.ModelState.ContainsKey("textbox1")
and then creating a tag such as follows
<span><%= ViewData.ModelState.ContainsKey("textbox1").Errors[0] %></span>
the helper does a bit more null value checking but you get the idea.

Related

Asp.net MVC 5 model validation regex not validating special characters

I have using ASP.NET MVC 5 and for validation I am using the regular Jquery unobtrusive validation library.
Currently I am facing an issue, The regular expression validation is working all right on client side but on server side its not validating the value.
[RegularExpression(#"^[0-9]{19}$", ErrorMessage = "Invalid Value")]
public string Value{ get; set; }
this is the simple regular expression to validate 19 digits. Its working fine on client side it'll now allow ' or - or any thing to pass on but if i submit directly to server than the model is not being validated.
Do I need to do some thing special?
ModelBinding ( the process of mapping post/get values to a complex model) occurs when you send data via post/get/put/delete requests, if you are manually creating a class with validation classes somewhere those data/validation annotations won't apply.
you can validate models manually - Validate list of models programmatically in ASP.NET MVC
That said, there is a library called PostSharp that can enforce those rules even when you are creating custom object/models outside of MVC ( CodeContracts ) and if it doesn't validate it throws an exception. Keep in mind that this library is paid but it has free version available that might fit your needs.

ASP.NET Web Pages 2 Select Value Validation

I figure this must be so simple and I'm missing something really obvious. I want to validate the selected value of a select input on an ASP.NET Web Pages 2 form using the built in validators but it doesn't look possible so far.
For example:
Validation.Add("my-select", Validator.ValueEquals("Some Value"));
Where Validator.ValueEquals would compare the selected value to the supplied parameter value "Some Value". I realize I could do:
if(Request["my-select"] != "Some Value") {
Validation.AddFormError("Invalid option selected");
}
But then I don't have the error message associated with the field and it will only appear if I'm rendering the validation summary at the top of the form.
What am I missing?
I've cracked the code! Unfortunately the solution is outside of the scope of the built in Validation and Validators static methods but I was able to achieve what I needed by using the following in place of the using the Validation class.
if(Request["my-select"] != "Some Value") {
ModelState.AddError("my-select", "Invalid option selected");
}
Then check if the ModelState is valid when checking Validation.IsValid():
if(ModelState.IsValid && Validation.IsValid()) {
// More codes...
}
It's kind of cool that ModelState is available but it really seems clunky that this isn't handled by the Validation and Validator classes.
You could use the EqualsTo validator and compare the supplied value to a hidden field value, or if you are worried that users might tamper with the hidden field value, you can write your own custom validator. I've blogged how to do that: http://www.mikesdotnetting.com/Article/195/ASP.NET-Web-Pages-Creating-Custom-Validators

Model Binding and Validation Errors

I am using asp.net MVC3 and I am very new to this technology.
My models are designed in such a way that the properties will throw validation errors if the data is invalid. In this case, the properties are not set with invalid data.
When I redisplay my editing-view, validation error messages are shown; however the values that the user previously entered are gone because the model that it is bound to only contains the old-valid data.
For example, say I had a Person class and the Name property cannot be a null or empty string otherwise it throws a validation exception and prevents the property from being set. Now say the user removes the value from the Name property and tries to save the Person from the web. A validation exception will be thrown and handled properly to add the error to the ModelState so that it is displayed on the screen; however the old value for the Name is redisplayed since the invalid, empty string never made it into the property.
I do not know how to solve this problem and any advice on the issue would be greatly appreciated.
My advise is allow invalid data but use validation attributes. You wont save invalid entities so there is no problem and this is the standard approach these days. If you don't want do that, there is no easy solution. Most simple solution would be using the info from Request.Form
You should implement IValidatableObject to performe this kind of validation at server side.
From MSDN IValidatableObject Interface:
Provides a way for an object to be invalidated.
Theres an exemple here Using IValidatableObject Custom Validation, also from MSDN.
The solution to this problem was to create a ViewModel that allowed invalid data to be entered into this. This solution also simplified my ModelBinder classes because it took on most of the work.

ASP.Net MVC elegant UI and ModelBinder authorization

We know that authorization's stuff is a cross cutting concern, and we do anything we could to avoid merge business logic in our views.
But I still not find an elegant way to filter UI components (e.g. widgets, form elements, tables, etc) using the current user roles without contaminate the view with business logic. same applies for model binding.
Example
Form: Product Creation
Fields:
Name
Price
Discount
Roles:
Role Administrator
Is allowed to see and modify the Name field
Is allowed to see and modify the Price field
Is allowed to see and modify the Discount
Role Administrator assistant
Is allowed to see and modify the Name
Is allowed to see and modify the Price
Fields shown in each role are different, also model binding needs to ignore the discount field for 'Administrator assistant' role.
How would you do it?
On way I could think to do this is create your own versions of the input extension methods. For example instead of TextBox you could create TextBoxRoles and define it like this:
public static MvcHtmlString TextBoxRoles(
this HtmlHelper htmlHelper,
string name,
string RolesEdit,
string RolesView
)
Then in code it would look like this:
<%= Html.TextBoxRoles("Price", "Administrator","Administrator,Assistant") %>
Then your implementation of TextBoxRoles would check the roles of the current user via User.IsInRole() to determine what should appear on the page.
Of course you would have to do this for every input extension method you use.
Since you already have both the current user and access to the authorization provider in your controllers this is an ideal responsibility for them. Using a naive implementation you might pass a collection of widgets to your view after you filtered which widgets the current user has access to. In the case of your form field, things might get hairy when you consider client side validation.
The binding part would be the most straight forward of all, having a custom binder for these special cases will do the trick specially well since it will have access to the controller context and you can grab the current user from there and bind the values according to your role definitions.
What about something like LinFu, an AOP framework? If it's crosscutting, then declare it is so and treat it as such.

Given a user control with a form containing validation can I validate entirely server side?

We have an existing User Control that was built to dynamically generate a web form for an end user. This form includes required field validators, custom validators that use server side code and Regular Expression validatiors.
We now have a need to use all these validators to verify that all the needed data is entered when using a separate ordering process that cannot be validated in the same way, but has the same validation requirements before it is added to the database.
I would like to use this user control to validate the input by passing it all the values and checking the validation summary. The only way I know how to do this is to render it to a page on the client side and trigger the form submit.
Is there any way to populate and validate a web form entirely on the server side?
It is definitely possible to create an instance of an .aspx page and invoke it on the fly, although it can be fraught with complications depending on what you are doing. Here's the basic idea:
Page instance = BuildManager.CreateInstanceFromVirtualPath(
"/myPath/myPage.aspx",
typeof(MyPageCodeBehindType)) as Page;
Presumably now you can call instance.ProcessRequest(HttpContext.Current) on it and have it go through the Page lifecycle. Again presumably you can check instance.IsValid and see if your Validators worked or not.
I say presumably because I have very little experience with this. Give it a shot - maybe check out the BuildManager class for some more examples.
EDIT: Looks like you can do this:
UserControl instance = (UserControl)BuildManager.CreateInstanceFromVirtualPath(
"~/Controls/Somefile.ascx", typeof(UserControl));
Yes, have you looked into LoadControl?
Dim dp As missico_UserControls_DropDownListDeviceProfile = LoadControl("~/missico/UserControls/DropDownListDeviceProfile.ascx")
'Dim dp As missico_UserControls_ComboDeviceProfile = LoadControl("~/missico/UserControls/ComboDeviceProfile.ascx")
Dim DeviceID As Integer
Dim MarketID As Integer = 0
DeviceID = dr("DeviceID").ToString
dp.SelectedValue = ProfileID
dp.DeviceID = DeviceID
dp.ID = "d" & DeviceID & "m" & MarketID
dp.OnClientChange = "pc(this);"
dp.ShowLabel(CBool(gscID = 1))
LoadControl should work for you. Yet, if the user control is not designed for true standalone operation, you could create a page that wraps the user control. Do a server transfer to the page. Have the page populate the user control, validate it, process the output, then transfer to an acknowledgement/error/original page.
I have used both these techniques, but can't find the server transfer code right now.
Not sure. It may be possible to create an instance of your user control's class, populate its fields by setting the .Text fields for each of its controls, call .Validate() on it, and check its isValid() value.
If that doesn't work, you may be better off designing separate validation for the "separate ordering process", if it is feasible. Can you give more details on how that is implemented?

Resources