Struts 2 Action Message - not displayed on the UI - struts2

I want to display an info message to the user on submit of the action but the message is not getting displayed. It works if I use addActionError but I want to display as an info message and hence using the addActionMessage. Please let me know where I went wrong.
public void validateUser() {
List<Product> existingProductList = new ArrayList<Product>();
try {
IProductRepository productRepository = daoRepository
.getProductRepository();
existingProductList = digestRepository
.searchDigests(null, null);
} catch (Exception e) {
e.printStackTrace();
}
for (Product product: existingProductList ) {
if (prod.getQuartzNumber().equalsIgnoreCase(
product.getQuartzNumber())) {
addActionMessage("The Quartz number entered already exists");
break;
}
}
}
Below is my jsp code:
<div id="content-wrapper">
<div id="product_create_header">
<h2>Create a New product</h2>
</div>
<!-- Error messages -->
<dl id="dyna_product_create_errors" class="error"></dl>
<form id="product_create_form" method="post">
<!-- product identifiers -->
<!-- product details -->
<fieldset id="product_create_details">
<legend>product Details</legend>
<div class="form-element">
<label for="product_create_name">Name:</label><br />
<input id="product_create_name" type="text" name="product.name" value="" maxlength="256" /><br />
<span id="product_create_name_error" class="error"></span>
</div>
<div class="form-element">
<label for="product_create_presentation_order">Quartz Order:</label><br />
<input id="product_create_presentation_order" type="text" name="product.quartzOrder" value="" maxlength="256" /><br />
<span id="product_create_presentation_order_error" class="error"></span>
</div>
</fieldset>
<!-- Form buttons -->
<div id="product_create_buttons" class="formButtons">
<button id="product_create_button_cancel" type="button" title="Reset" onclick="resetproductCreateForm();">Reset</button>
<button id="product_create_button_submit" type="button" title="Submit" onclick="createproduct();">Submit</button>
</div>
</form>
</div>
I see that they have added
for displaying the error, not sure how to display for messages
Below is my js code:
function createproduct() {
dojo.xhrPost( {
url :"services/product/create",
handleAs :"json",
preventCache :"true",
load : function(returnObject, ioArgs) {
if (returnObject.status == "success") {
product = returnObject.body;
displayproductDetail();
}
else if (returnObject.status == "input") {
var errorList = dojo.byId("dyna_product_create_errors");
handleActionErrors(returnObject.actionErrors, errorList);
handleActionMessage(returnObject.actionMessages, messageList);
handleCreateproductsFieldErrors(returnObject.fieldErrors);
}
else if (returnObject.status == "error") {
resetproductSearchFormErrors();
var errorList = dojo.byId("dyna_product_create_errors");
handleActionErrors(returnObject.actionErrors, errorList);
}
},
error : function(error) {
handleHTTPError(error);
},
form :'product_create_form'
});
}

private String myActionMessage;//Getter and setter Method
public void validateUser() {
List<Product> existingProductList = new ArrayList<Product>();
try {
IProductRepository productRepository = daoRepository
.getProductRepository();
existingProductList = digestRepository
.searchDigests(null, null);
} catch (Exception e) {
e.printStackTrace();
}
for (Product product: existingProductList ) {
if (prod.getQuartzNumber().equalsIgnoreCase(
product.getQuartzNumber())) {
addActionMessage("The Quartz number entered already exists");
getMyActionMessage("The Quartz number entered already exists");
break;
}
}
}
And your result.jsp file
<s:actionmessage/>
<s:property value="myActionMessage"/>

Related

Checkbox Form Submit trigger Logout in Identity EntityFramework on _loginpartial-C# asp.net MVC

I have a checkbox(justdoit) on asp.net MVC create view. If checkbox checked, it submits#onclick = "document.forms[0].submit() value and according to that, if else condition disable or enable other dropbox form("Status) in view.It was working without problem. After I integrated authorization to page(Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="6.0.10), I added _loginpartial to _layout.cshtml page. Then I log in page with authorised user and enter create item page,when I check to checkbox(onlick submit works), log out is trigered and I log out the site and find myself on the indexpage. After that I tried to create item without login, it works without problem. Therefore I think checkbox submit trigger the logout.(Project.Identity.Pages.Account.LogoutModel: Information: User logged out.) How Can I solve that problem?
Thank you for answer in advance
Code in the view:
#Html.CheckBox("Justdoit", false, new { #onclick = "document.forms[0].submit();" })
Justdoit
<br />
#if(Convert.ToBoolean(ViewBag.Justdoit))
{
<div class="form-group">
<label asp-for="Status" class="control-label">Status (Choose One)</label>
<select asp-for="Status" class="form-control" id="Status" disabled>
<option>Completed</option>
</select>
<span asp-validation-for="Status" class="text-danger"></span>
</div>
}
else
{
<div class="form-group">
<label asp-for="Status" class="control-label">Status (Choose One)</label>
<select asp-for="Status" class="form-control" id="Status" >
<option>Completed</option>
<option>Plan</option>
<option>Do</option>
<option>Study</option>
<option>Act</option>
</select>
<span asp-validation-for="Status" class="text-danger"></span>
</div>
}
</td>
Code in the _loginpartial
<li class="nav-item">
<form id="logoutForm" class="form-inline" asp-area="Identity" asp-page="/Account/Logout" asp-route-returnUrl="#Url.Action("Index", "Home", new { area = "" })">
<button id="logout" type="submit" class="nav-link btn btn-link text-dark">Logout</button>
</form>
</li>
Item controller- It logs out before calling ViewBag.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult>Create(bool Justdoit,[Bind("Id,Title,Description,MainBody,Team,Owner,StartDate,Status,Justdoit,Category")] Suggestion suggestion)
{
ViewBag.Justdoit = Justdoit;
if (ModelState.IsValid)
{
_context.Add(suggestion);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
return View(suggestion);
}
Logout model View
#page
#model LogoutModel
#{
ViewData["Title"] = "Log out";
}
<header>
<h1>#ViewData["Title"]</h1>
#{
if (User.Identity.IsAuthenticated)
{
<form class="form-inline" asp-area="Identity" asp-page="/Account/Logout" asp-route-returnUrl="#Url.Page("/", new { area = "" })" method="post">
<button type="submit" class="nav-link btn btn-link text-dark">Click here to Logout</button>
</form>
}
else
{
<p>You have successfully logged out of the application.</p>
}
}
</header>
Logout model cshtml.cs file
public class LogoutModel : PageModel
{
private readonly SignInManager<ApplicationUser> _signInManager;
private readonly ILogger<LogoutModel> _logger;
public LogoutModel(SignInManager<ApplicationUser> signInManager, ILogger<LogoutModel> logger)
{
_signInManager = signInManager;
_logger = logger;
}
public async Task<IActionResult> OnPost(string returnUrl = null)
{
await _signInManager.SignOutAsync();
_logger.LogInformation("User logged out.");
if (returnUrl != null)
{
return LocalRedirect(returnUrl);
}
else
{
// This needs to be a redirect so that the browser performs a new
// request and the identity for the user gets updated.
return RedirectToPage();
}
}
}
Enable or Disable form based on Condition in ASP.Net MVC. Condition is created by clicking the checkbox. I want to use that feature on the authorized page.

I can't make client side validation working on an ASP.NET application

my issue
I try to create a custom validator with client validation.
But client validation side doesn't work, I can't understand why.
This is a .NET Core 3.1 application.
my code
The validator:
public class ExcludeCharAttribute : ValidationAttribute, IClientValidatable
{
private readonly string _chars;
public ExcludeCharAttribute(string chars)
: base("{0} contains invalid character.")
{
_chars = chars;
}
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
if (value != null)
{
var valueAsString = value.ToString();
for (int i = 0; i < _chars.Length; i++)
{
if (valueAsString.Contains(_chars[i]))
{
var errorMessage = FormatErrorMessage(validationContext.DisplayName);
return new ValidationResult(errorMessage);
}
}
}
return ValidationResult.Success;
}
//new method
public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
var rule = new ModelClientValidationRule();
rule.ErrorMessage = FormatErrorMessage(metadata.GetDisplayName());
rule.ValidationParameters.Add("chars", _chars);
rule.ValidationType = "exclude";
yield return rule;
}
}
For testing I created this test dto:
public class TestDto
{
[ExcludeChar("123456")]
public string Prop1 { get; set; }
[Required]
public string Prop2 { get; set; }
}
and that form:
<div class="row">
<div class="col-md-4">
<form asp-action="TestValidator">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="Prop1" class="control-label"></label>
<input asp-for="Prop1" class="form-control" />
<span asp-validation-for="Prop1" class="text-danger"></span>
<label asp-for="Prop2" class="control-label"></label>
<input asp-for="Prop2" class="form-control" />
<span asp-validation-for="Prop2" class="text-danger"></span>
</div>
<div class="form-group">
<input type="submit" value="Save" class="btn btn-primary" />
</div>
</form>
</div>
</div>
<div>
<a asp-action="Index">Back to List</a>
</div>
#section Scripts {
<script src="~/lib/jquery-validation/dist/jquery.validate.min.js"></script>
<script src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js"></script>
<script src="~/js/validator.js"></script>
}
And of course this validation js (validator.js):
$.validator.unobtrusive.adapters.addSingleVal("exclude", "chars");
$.validator.addMethod("exclude", function (value, element, exclude) {
if (value) {
for (var i = 0; i < exclude.length; i++) {
if (jQuery.inArray(exclude[i], value) != -1) {
return false;
}
}
}
return true;
});
What happen
When testing no client validation is run.
When inspecting code I don't see any data-* attributes for Prop1:
But it's OK for Prop2.
I think this is why it does not work.
What I tested
Tested other online samples.
Tested I loaded all the JS:
Tested CDN version of the scripts
What I need
Now I have no idea what to do. Does anybody have an ideau about what is lacking?
thank you
I copied your custom validation code and test in my side but it worked well, could you pls check the differences between your code and mine? I'm sure the view code is the same, and in validation class you may check the using packages.
validation class:
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Web.Mvc;
namespace WebAppMvc.Models
{
public class ExcludeCharAttribute : ValidationAttribute, IClientValidatable
{
private readonly string _chars;
public ExcludeCharAttribute(string chars)
: base("{0} contains invalid character.")
{
_chars = chars;
}
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
if (value != null)
{
var valueAsString = value.ToString();
for (int i = 0; i < _chars.Length; i++)
{
if (valueAsString.Contains(_chars[i]))
{
var errorMessage = FormatErrorMessage(validationContext.DisplayName);
return new ValidationResult(errorMessage);
}
}
}
return ValidationResult.Success;
}
//new method
public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
var rule = new ModelClientValidationRule();
rule.ErrorMessage = FormatErrorMessage(metadata.GetDisplayName());
rule.ValidationParameters.Add("chars", _chars);
rule.ValidationType = "exclude";
yield return rule;
}
}
}
Model:
using System.ComponentModel.DataAnnotations;
namespace WebAppMvc.Models
{
public class UserModel
{
[Key]
[ExcludeChar("123456")]
public string id { get; set; }
public int userId { get; set; }
}
}
And this is my controller method:
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Create([Bind("id,userId")] UserModel user)
{
if (ModelState.IsValid)
{
return RedirectToAction("Index");
}
return View(user);
}
This is the view:
#model WebAppMvc.Models.UserModel
<h4>Test</h4>
<hr />
<div class="row">
<div class="col-md-4">
<form method="post">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="id" class="control-label"></label>
<input asp-for="id" class="form-control" />
<span asp-validation-for="id" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="userId" class="control-label"></label>
<input asp-for="userId" class="form-control" />
<span asp-validation-for="userId" class="text-danger"></span>
</div>
<div class="form-group">
<input type="submit" value="Create" class="btn btn-primary" />
</div>
</form>
</div>
</div>

I have a question how to add input fields values with same name into the database using entity framework? Below is my code,

This is my HomeWithIndentityController
namespace MVC.CRUDDynamicFormTest.Controllers
{
public class HomeWithIndentityController : Controller
{
// GET: HomeWithIndentity
public ActionResult WithIndex()
{
return View();
}
public ActionResult GetData()
{
using (DynamicCRUDDatabase2Entities db = new DynamicCRUDDatabase2Entities())
{
List<DynamicCRUDTable2> dynamicCRUDTable2s = db.DynamicCRUDTable2.ToList<DynamicCRUDTable2>();
return Json(new { data = dynamicCRUDTable2s }, JsonRequestBehavior.AllowGet);
}
}
[HttpGet]
public ActionResult Add(int id = 0)
{
return View(new DynamicCRUDTable2());
}
[HttpPost]
public ActionResult Add(DynamicCRUDTable2 obj)
{
using (DynamicCRUDDatabase2Entities db = new DynamicCRUDDatabase2Entities())
{
db.DynamicCRUDTable2.Add(obj);
db.SaveChanges();
return Json(new { succces = true, message = "saved Successfully" }, JsonRequestBehavior.AllowGet);
//return RedirectToAction("Index", "Home");
}
}
}
}
this is my entity model class
public partial class DynamicCRUDTable2
{
public int Id { get; set; }
public string FirstName { get; set; }
}
This my View
<form action="~/HomeWithIndentity/Add" method="POST" onsubmit="return Submitform(this)">
<input data-val="true" id="Id" name="Id" type="hidden" />
<label>First Name</label>
<input type="text" name="FirstName[]" class="form-control" />
<input type="text" name="FirstName[]" class="form-control" />
<br />
<br />
<div>
<input type="submit" value="Submit" class="btn btn-success" />
<input type="reset" value="Reset" class="btn btn-danger" />
<a class="btn btn-danger" href="~/Home/Index">Cancel</a>
</div>
</form>
In the above view i want to add the firstname input field values to the Database dynamicallly.but it does not working can you let me know why?What errors i have done.
does anyone know how to do that?

Kendo validator always returns false with when multiple check boxes exists

In ASP.NET i have the following
public class TestController : Controller
{
public IActionResult Index()
{
return View(new MyModel()
{
Activities = new Activity[]
{
new Activity(){ },
new Activity(){ }
}
});
}
}
public class MyModel
{
public IList<Activity> Activities { get; set; }
}
public class Activity
{
public bool IsActive { get; set; }
}
cshtml
#model Metatasker.Integration.UI.Controllers.MyModel
<form id="myform">
#for (int i = 0; i < Model.Activities.Count; i++)
{
#Html.CheckBoxFor(x => x.Activities[i].IsActive)
}
</form>
<button id="btn">Click Me</button>
<script type="text/javascript">
$(function () {
function validate() {
var kendoValidator = $('#myform').kendoValidator().data("kendoValidator");
return kendoValidator.validate();
}
$("#btn").click(function () {
alert(validate());
})
})
</script>
I am using Kendo's Validate method to validate form. In code above when i have multiple CheckBoxes The validate() method always returns false. If i have single check box then it works.
I have jsfiddle demo. The html in jsfiddle is a rendered Razor view.
DEMO
Try the following snippet.
<form id="form1">
<!-- Kendo UI Checkbox -->
<input type="checkbox" id="checkboxMale" name="Gender" required />
<label for="checkbox">Male</label>
<span class="k-invalid-msg" data-for="Gender"></span>
<input type="checkbox" id="checkboxFemale" name="Gender" required />
<label for="checkbox">Female</label>
<span class="k-invalid-msg" data-for="Gender"></span>
<button>Validate</button>
</form>
<script>
$(document).ready(function() {
var validator = $("#form1").kendoValidator().data("kendoValidator");
});
</script>
You will notice that the validator treats only true values as inputs which are filled, else it serves up the required validation message. Each check box is validated individually.
So, I suggest using a custom rule.
<form id="myform">
<ul validationMessage="You must enter a gender">
<li>
<input id="activity1" name="activity" type="checkbox" value="activity1" />
<label for="activity1">Activity1</label>
</li>
<li>
<input id="activity2" name="activity" type="checkbox" value="activity2" />
<label for="activity2">Activity2</label>
</li>
</ul>
<button>Validate</button>
</form>
<script>
$("#myform").kendoValidator({
rules: {
customRule1: function(input) {
if (input.is("[name=activity]")) {
return $("[name='activity']:checked").length > 0;
}
}
},
messages: {
customRule1: "Atleast one activity should be selected."
}
});
</script>
There is also a demo which uses radio buttons, which you can refer to.

How to pass a complex model back to the controller in asp.net mvc

New to web development.
I have a view that allows user to select an excel file.
When submit "preview" button is pressed file is read and data is sent back to the user to preview the data.
Then I want to be able send the model back to the control for db upload.
(this is the part I'm struggling with).
ViewModel:
public class UploadItemsViewModel
{
public List<Item> Items { get; set; }
public int CompanyID { get; set; }
public Company Company { get; set; }
public HttpPostedFileBase upload { get; set; }
public UploadJournalsViewModel()
{
Items = new List<Item>();
}
}
Controller:
public ActionResult Upload(FormCollection formCollection, int CompanyID)
{
if (Request != null)
{
HttpPostedFileBase file = Request.Files["UploadedFile"];
if ((file != null) && (file.ContentLength > 0) && !string.IsNullOrEmpty(file.FileName))
{
string fileName = file.FileName;
string fileContentType = file.ContentType;
byte[] fileBytes = new byte[file.ContentLength];
var data = file.InputStream.Read(fileBytes, 0, Convert.ToInt32(file.ContentLength));
}
}
UploadItemsViewModel itmViewModel = new UploadItemsViewModel { Company = db.Companies.Find(CompanyID), CompanyID = CompanyID };
return View(itmViewModel);
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Upload(UploadItemsViewModel itmViewModel, string Preview, string Upload)
{
if (ModelState.IsValid)
{
if (itmViewModel.upload != null && itmViewModel.upload.ContentLength >0)
{
try
{
itmlViewModel.Items = App.Services.ItemsMassUploadFileRead.ReadExcelFile(itmViewModel.upload, db.Companies.Find(itmViewModel.CompanyID));
if (string.IsNullOrEmpty(Preview))
{
foreach (var itm in itmViewModel.Items)
{
itm.StartDate = DateTime.Today;
itm.CompanyID = itmViewModel.CompanyID;
itm.User = null;
itm.Items.Add(itm);
db.SaveChanges();
}
return View();
}
else
{
return View(itmViewModel);
}
} }
catch (Exception ex)
{
ModelState.AddModelError("File", ex.Message.ToString());
return View(itmViewModel);
}
}
else
{
ModelState.AddModelError("File", "Please Upload Your file");
}
}
return View(itmViewModel);
}
View:
#using (Html.BeginForm("Upload", "ItemsUpload", null, FormMethod.Post, new { enctype = "multipart/form-data" }))
{#Html.AntiForgeryToken()
#Html.HiddenFor(model => model.CompanyID)
<div class="form-group">
<div class="input-group">
<label class="input-group-btn">
<span class="btn btn-default">
Browse… <input type="file" style="display: none;" accept=".xlsx" name="upload">
</span>
</label>
<input type="text" class="form-control " readonly>
</div>
<span class="help-block">
Please use a provided Excel template
</span>
</div>
<div class="form-group">
<input type="submit" value="Preview" name ="Preview" class="btn btn-default" disabled style="display: none" id="submit"/>
</div>
<div class="form-group">
<input type="submit" value="Upload" name="Upload" class="btn btn-default" id="Upload" />
</div>
<div class="help-block" id="previewHelp" style="display: none">
Preview results and scroll down to upload data to the database.
</div>
if (Model.Journals.Count != 0)
{
table here to preview the upload
}
After clicking the Upload button model comes back without the "items" collection.
The Items list will be always null in the controller, because you don't rendered any input on the View with the name Items

Resources