IZPACK custom DataValidator unable to read custom panel user input - izpack

I have created a sample installer using IZPACK API. In this, i have created a custom panel class by extending IzPanel. After that i created a panel data validator by implementing DataValidator interface.
I have given its entry in install.xml as shown below:
<panel classname="TestInstallation" id ="TestInstallation">
<validator classname="com.izforge.izpack.panels.TestValidator"/>
</panel>
Validator is running fine and showing error message. Here, I need to show error message depending upon wrong user input combination entered in panel multiple fields. But, i am unable to read user entered data in my custom data validator(TestValidator) and getting null. AutomatedInstallData.getAttribute("") as well as AutomatedInstallData.getVariable("") both methods are returning null in my custom data validator.
Please help and let me know if i am missing something here.
Thanks in Advance !!!

Since you have you have your own validator by implementing the DataValidator intereface, you can get the user input from the InstallData object in your validateData overriden method. Eg.
#Override
public Status validateData(InstallData data) {
if (data.getVariables().get("MyFieldVariable");) {
return Status.OK;
} else {
return Status.ERROR;
}
}
"MyFieldVariable" is the name of the variable used in your custom panel. I guess you must have several input fields to validate against. But at least in this example it would be:
<field type="text" variable="MyFieldVariable">
<spec txt="My own field to validate" id="MyFieldVariable" size="15" set="" />
</field>
For the error to be displayed an Status.ERROR is returned from validateData(InstallData data) and you should override in your validator:
#Override
public String getErrorMessageId() {
return errorMsg;
}
This is available and tested with izpack 5.0.0-rc1. Mind that you should also then have the right maven dependencies:
<dependencies>
<dependency>
<groupId>org.codehaus.izpack</groupId>
<artifactId>izpack-panel</artifactId>
<version>5.0.0-rc1</version>
</dependency>
<dependency>
<groupId>org.codehaus.izpack</groupId>
<artifactId>izpack-api</artifactId>
<version>5.0.0-rc1</version>
</dependency>
</dependencies>

Related

how to show all the errors on a page in one shot (submit button) by client side validation in mvc .net core

I have a page with many required fields. So when I click submit button required validation is firing for the first field then the second then the third and so on...
What I need to do here is , When I click on submit I have to show all errors on a page in one shot.
My requirement is to achieve this only by validating client side.
I am using an .Net core MVC application.
Below is the screenshot of my page
Can I achieve this.. Please help me..
Thanks !!
I can give you an idea to do your job using jquery custom validation.Please refer my solution.
Add custom style class to your required fields.
Example :
<input type="text" class="req-cls" >
Write Jquery function to Check Validation
$(document).ready(function () {
$('#btn1').click(function (e) {
var isValid = true;
$('.req-cls').each(function () {
if ($.trim($(this).val()) == '') {
isValid = false;
$(this).css({
"border": "1px solid red",
"background": "#FFCECE"
});
}
else {
$(this).css({
"border": "",
"background": ""
});
}
});
if (isValid == false)
e.preventDefault();
});
});
See Example here : https://jsfiddle.net/Shalitha/q2n8L9wg/24/
Just add this line in your .cshtml
<div class="validation-summary-valid" data-valmsg-summary="true">
<ul>
<li style="display: none;"></li>
</ul>
</div>
Since you need client side we are talking about JS. But with razor you can validate a few results using the model annotations. For example let's say you have this object.
public class UserCreationVO
{
[Required]
[StringLength(255)]
public string Username { get; set; }
}
Now what you need to do in your frontend (meaning your .cshtml file) is to tell asp.net to use this properties to validate. So for example:
#model UserCreationVO
<form method="post">
<input asp-for="UserName" />
<span asp-validation-for="UserName"></span>
</form>
As you can see above using asp-for is a great way to create validations using your models. Be careful you must pass as a model the object you want to validate. The asp-for tag shows a model property. So you can't pass it in a Viewbag or something. This produces some automatic html and js for you and handles it.
Furthermore you should always validate the result nevertheless in the controller. Because client side validation is for performance reasons and user experience and doesn't offer any kind of security:
public IActionResult CreateUser(UserCreationVO user)
{
if(!ModelState.IsValid)
return your_error;
}
Last but not least: You must include the JQuery unobtrusive validation library. Furthermore if you have some extra requirements like checking if a username exists (Which can't be done without contacting the server) then you can use the [Remote] attribute.
More info and reading about front-end validation with razor: here
How to use a remote attribute: Using remote validation with ASP.NET Core
EDIT:
So generally I advise to use models and create them. As you say policy is required in one form but not in another. What you should do to have a maintanable code where you simply change the attribute of your model and the validation happens you need to create a different VO. For example:
public class CreatePolicyVO
{
[Required]
public string PolicyNumber {get; set;}
}
And another object for example updating:
public class UpdatePolicyVO
{
public string PolicyNumber {get; set;}
}
Because you also need to validate them in the controller. So passing a different object allows you to use ModelState.IsValid and other MVC and razor features. Generally if a field is required in one case and not in another then you need a different model.
First, we need to add the JQuery,jquery.validate & jquery.validate.unobtrusive in our views.
<script src="https://ajax.aspnetcdn.com/ajax/jquery/jquery-2.2.0.min.js"></script>
<script src="https://ajax.aspnetcdn.com/ajax/jquery.validate/1.16.0/jquery.validate.min.js"></script>
<script src="https://ajax.aspnetcdn.com/ajax/jquery.validation.unobtrusive/3.2.6/jquery.validate.unobtrusive.min.js"></script>
Then in View add required data-* attributes like:
<label for="Name">Name</label>
<input type="text" data-val="true" data-val-length="Length must be between 10 to 25" data-val-length-max="25" data-val-length-min="10" data-val-required="Please enter the name" id="Name" name="Name" value="" />
<span class="field-validation-valid" data-valmsg-for="Name" data-valmsg-replace="true"></span>
<br />
You could see that it has added the several attributes starting with data-*.
The data-* attributes are part of the HTML5, which allow us the add extra information (metadata) to the HTML element.
The Javascript unobtrusive library reads the data-val attributes and performs the client side validation in the browser when the user submits the form. These Validations are done before the form is sent over an HTTP. If there is a validation error, then the request will not be sent.

Android Data Binding "cannot find method"

This is seemingly old at this point. I have been reviewing Android Data Binding Documentation
As well pouring over posts here on SO however nothing seems to work.
No matter how I format the XML I get the same results. When I originally got this working (using lambda without passing arguments) took me a lot of trial and error. Now that i need to pass View in an onClick, im back to trial and error yet nothing is functional.
MainViewModel.java
private void navClicked(#NonNull View view) {
switch (view.getId()) {
case R.id.btn1:
break;
case R.id.btn2:
break;
}
}
public void testBtn() {}
activity_main.xml
<data>
<variable
name="mainViewModel"
type="com.example.viewmodel.MainViewModel" />
</data>
<!-- Works perfectly -->
<!-- however I would need a method for every button and that becomes redundant -->
<Button
android:id="#+id/testBtn"
android:onClick="#{() -> mainViewModel.testBtn()}"
android:text="#string/testBtn" />
<!-- "msg":"cannot find method navClicked(android.view.View) in class com.example.viewmodel.MainViewModel" -->
<Button
android:id="#+id/btn1"
android:onClick="#{(v) -> mainViewModel.navClicked(v)}"
android:text="#string/btn1" />
<!-- "msg":"cannot find method navClicked(android.view.View) in class com.example.viewmodel.MainViewModel" -->
<Button
android:id="#+id/btn2"
android:onClick="#{mainViewModel::navClicked}"
android:text="#string/btn2" />
<!-- "msg":"Could not find identifier \u0027v\u0027\n\nCheck that the identifier is spelled correctly, and that no \u003cimport\u003e or \u003cvariable\u003e tags are missing." -->
<!-- This is missing (view) in the lambda - makes sense to fail -->
<Button
android:id="#+id/btn3"
android:onClick="#{() -> mainViewModel.navClicked(v)}"
android:text="#string/btn2" />
navClicked() was private...
// **denotes change, will not compile like that**
**public** void navClicked(#NonNull View view) {
switch (view.getId()) {
case R.id.btn1:
break;
case R.id.btn2:
break;
}
}
Once I tried this and it worked:
XML:
android:onClick="#{() -> model.clickEvent(123)}"
Model:
public void clickEvent(int id) {...}
I used string for id but I think it also works with integer.

Kendo ui - how to tie validation to mvc model attributes

From reading the posts in this thread - and being unable to post the question there for some bizarre reason :( I will ask it here in hope of getting a solution
Am I write in saying that I have to do validation like below..
I add the html5 attribute (data-required-msg/validationMessage) to the textbox and the required attribute as well..
I make a span for the invalid msg and tie it to the field with the "data-for" attribute. The message "Please enter name" should appear in this span then.
Questions
Is this the only way to work with this?
Is there no way for me to display the proper error message ("Error Message I want to show"), as in any way to tie to the mvc attributes on the ViewModel. As another poster said this is a lot more scalable/re-usable and better design.
Using a data-for="Name" is very brittle as a change in the Model field name will not reflect there and that could be forgotten about hence delivering buggy software. You are losing the type safety of something like
#Html.ValidationMessageFor(m=> m.Name)
Code
public class AViewModel
{
[Required(ErrorMessage="Error Message I want to show")]
public string Name { get; set; }
}
<div class="validation-wrapper">
<div class="input-wrapper">
#Html.TextBoxFor(m => m.Name, new { placeholder = "eg. John Smith", data_required_msg="PleaseEnter name", required="required" } )
</div>
<span class="k-invalid-msg" data-for="Name"></span>
</div>
Cheers,
J
In order to be able to do what you are saying, you need to be using Kendo UI for ASP.NET MVC. With that you can continue using your DataAnnotations attributes and Html.ValidationMessageFor() helpers as before. All you will need to do is call $('[your_form_selector]').kendoValidator() after your form (or on document.ready()).

.net MVC 4 Authorization (Membership)

During my first steps in .NET MVC 4 I'm creating a web site and I would like to implement users authentication/authorization.
In my implementation I would like to be able to link controls to roles. For example, if I have 2 Roles in my system : Admin and User, the in some view say I have 3 inputs:
<input class="search-field rounded" id="field1" type="text"/>
<input type="submit" name="submit"/>
<input class="search-field rounded" id="field2" type="text"/>
<input type="submit" name="submit"/>
<input class="search-field rounded" id="field3" type="text"/>
<input type="submit" name="submit"/>
I would like that an Admin will be able to see and edit all 3 fields in this view, but a User should only see 2 of them, and be able to edit one of them (this is just an example).
So basically, I would like to be able to define permissions for controls, and a role should be consisted of a collection of permissions (If you can think of a better approach I would love to hear it).
So those are my constraints, and I see quite a few packages out there (such as Fluent Security, and Security Guard) that relates to the subject, but I'm not quite sure which is best to tackle my challenge if at all.
Is there a best practice to overcome this demand?
Any help is highly appreciated.
idlehands23 has shown how you might access and check roles but i'm guessing you want to use this functionality at the view level.
Within an action method, I usually pass HttpContext.User into the ViewBag or in the case of a strongly typed view you can pass the principal into your model and parse these values out as you wish. Then pass the model to the view like so.
return View(new ModelClass(HttpContext.User))
From here you can add additional code into the view logic to parse/check the roles and render the html with greater specificity using for example:
If (Model.User.IsInRole("Admin"))
{
//Render admin controls
//...
}
else
{
//Render User Controls
//...
}
Using the [Authorize(Role="Admin||User")] attribute on your action method would restrict access to an entire group of users. In such a case you would need two action methods and one or possibly two distinct views to render the content. However if you just want to limit it to ANY authorized user you can do like so:
[Authorize]
public ActionResult Index(){}
Then you can implement the logic at the view level with the certainty that they are authorized.
I have done it this way:
//In Controller
ViewBag.Roles = Roles.GetRolesForUser(User.Identity.Name);//viewbag because I'm assuming this isn't what you want to strongly type to your page.
//In View
#{
var roles = (Roles)ViewBag.Roles;
}
if(roles.contains("admin')) //put whatever you want in place of "admin"
{
//do something
}
in your controller you can give access to certain views or partial views this way
//in controller if you want it.
[Authorize(Roles = "Admin, ImportExport, Search")] //this is just for security
public ActionResult whatever(){}
*I use razor. replace # with <% %> if your not.
I ended up creating my own custom membership provider and role provider.
In my Role Provider I added a method
public bool UserHasPermission(string username, string permission) {...}
And in my view I'm doing:
#{
var roleProvider = Roles.Provider as MyCustomRoleProvider;
bool addressEditPermission = roleProvider.UserHasPermission(User.Identity.Name, "addressEditPermission");
}
Then I can manipulate my control:
#Html.TextBoxFor(model => model.Name, new { #readonly = addressEditPermission })
You just need to make sure your control has overloads that take HTML attributes.
I hope this helps someone..

Passing a GET parameter to ActionLink in ASP.NET

Sorry but I am new to C# and ASP.NET and I saw alot of posts about this problem but I quite didn't get it. I am trying to understand how to pass a GET parameter to an action thru HTML.ActionLink:
here is the the URL:
http://localhost:36896/Movies/SearchIndex?searchString=the
and my CSHTML page should look like this:
<input type="Text" id="searchString" name="searchString" />
#Html.ActionLink("Search Existing", "SearchIndex", new { searchString = "the"})
this hard coded parameter "the" is actually working, but how can I select the input element with id=searchString, with something like document.getElementById("searchString").value
Thanks,
If the value you want to send as GET parameter is not known on the server you cannot use the Html.ActionLink helper to add it. You need to use javascript to manipulate the existing link and append the parameter.
It looks like you have an input field that contains a search string and you want to send the value entered in this field to the server. A better way to handle this scenario is to use an HTML form with method="GET" instead of an ActionLink. This way you don't need to use any javascript - it's part of the HTML specification:
#using (Html.BeginForm("SearchIndex", "Movies", FormMethod.Get))
{
#Html.EditorFor(x => x.SearchString)
<button type="submit">Search</button>
}
Now when you click on the Search button the value entered in the SearchString field will automatically be sent to the SearchIndex action:
http://localhost:36896/Movies/SearchIndex?searchString=the
But if you absolutely insist on using an ActionLink you will have to write javascript to manipulate the href of the existing link when this link is clicked in order to append the value to the url. It's an approach I wouldn't recommend though because the HTML specification already provides you this functionality throughout HTML forms.
This makes the #Html.EditorFor refer to the Title field of the object, kinda in a random way but it works!
#using (Html.BeginForm ("SearchIndex", "Movies", FormMethod.Get))
{
#Html.EditorFor( x => x.ElementAt(0).Title)
<button type="submit">Search</button>
}
Still couldn't pass input parameter to the URL in the GET.
EDIT:
FINAL SOLUTION:
#Html.TextBox("SearchString")
<button type="submit">Filter</button>
and on the controller side, switch the input parameter. Basically it will automatically recognize the passed parameter.
public ActionResult SearchIndex(string searchString)
{
...
}