Nested Where(x => x.Condition = value, () => {}); fluentvalidation - asp.net

Current project:
ASP.NET 4.5.1
MVC 5
I need to know if I can nest When() statements like this:
When(x => x.Cond1 == val1,
() => {
When(x => x.SubCond1 == SubVal1,
() => {
When(x => x.Final1 == finalVal1,
() => {
RuleFor(x => x.Field1)
.NotEmpty().WithMessage("Should not be empty");
// a few more here
});
When(x => x.Final2 == finalVal2,
() => {
RuleFor(x => x.Field8)
.NotEmpty().WithMessage("Should not be empty");
// a few more here
});
});
When(x => x.SubCond2 == SubVal2,
() => {
RuleFor(x => x.Field16)
.NotEmpty().WithMessage("Should not be empty");
// a few more here
});
});
Because the last thing I want is to decorate 30+ form fields like this:
RuleFor(x => x.Field1)
.NotEmpty().WithMessage("Should not be empty")
.When(x => x.Cond1 == val)
.When(x => x.SubCond1 == SubVal1)
.When(x => x.Final1 == finalVal1);
That is just untenable.
None of the conditions require validation themselves, as none of them are actually user-editable fields (just user-selectable values); I just need to compare them against known values. I would use an if/else statement if that was actually more appropriate, which it isn’t.
The model is largely flat, with only the second-level When() representing an imported model, and the third-level being different ways to handle specific fields within the imported model.

You can't, but you can try and use Rule Sets to group your rules together. Also maybe check Cascade Mode.

Related

How to prevent when unknown property insert in input API post request?

I'm working on Asp.net core and applying back-end validation using Fluent Validation.
The problem is, When I pass unknown property from postman over post request so it gives true response. I want to validate that unknown property.
Fluent Validation Code:
public class ScheduleADemoValidator : AbstractValidator<ScheduleADemo>
{
public ScheduleADemoValidator()
{
RuleFor(x => x.FirstName).NotEmpty().WithMessage("FirstName is required").MaximumLength(20);
RuleFor(x => x.LastName).NotEmpty().WithMessage("LastName is required").MaximumLength(20);
RuleFor(x => x.Iam).NotNull().Must(x => x == false || x == true);
RuleFor(x => x.Iaminterestedin).NotEmpty().NotEqual("-None-").WithMessage("Iaminterestedin is required");
RuleFor(x => x.Email).NotEmpty().WithMessage("Email is required").EmailAddress();
RuleFor(x => x.Phone).NotEmpty().WithMessage("Phone is required").Matches("^([0-9]{3})?[-]([0-9]{3})?[-]([0-9]{4})$");
RuleFor(x => x.NABP).NotNull().Matches("^([0-9]{7})$");
RuleFor(x => x.Pharmacyname).NotEmpty().WithMessage("Pharmacyname is required").MaximumLength(20);
RuleFor(x => x.Legalbusinessname).Length(0, 20);
RuleFor(x => x.Address).MaximumLength(50);
RuleFor(x => x.City).MaximumLength(50);
RuleFor(x => x.State).NotEmpty().NotEqual("-None-").WithMessage("State is required").Length(2);
RuleFor(x => x.ZipCode).Matches("^([0-9]{5})$");
RuleFor(x => x.IheardofPrimeRxfrom).NotEmpty().NotEqual("-None-").WithMessage("IheardofPrimeRxfrom is required").MaximumLength(30);
RuleFor(x => x.Iamlookingtobuywithin).NotEqual("-None-").WithMessage("-None- is not accepted").MaximumLength(30);
RuleFor(x => x.Iwouldliketoseeademofor).NotEmpty().NotEqual("-None-").WithMessage("Iwouldliketoseeademofor is required").MaximumLength(30);
RuleFor(x => x.Message).NotNull().MaximumLength(50);
}
protected override bool PreValidate(ValidationContext<ScheduleADemo> context, ValidationResult result)
{
if (context.InstanceToValidate == null)
{
result.Errors.Add(new ValidationFailure("", "Iam must be true or false"));
return false;
}
return true;
}
}
My controller code:
if (!validationResult.IsValid)
{
return Json(new { failure = validationResult.Errors.First().ErrorMessage });
}
var _savingScheduleADemo = new SavingScheduleADemo(_contentManager, _contentItemDisplayManager, _updateModelAccessor, _contentDefinitionManager, _session, _idGenerator);
var result = await _savingScheduleADemo.CreateScheduleADemo(
scheduleADemo.FirstName,
scheduleADemo.LastName,
scheduleADemo.Iam,
scheduleADemo.Iaminterestedin,
scheduleADemo.Email,
scheduleADemo.Phone,
scheduleADemo.NABP,
scheduleADemo.Pharmacyname,
scheduleADemo.Legalbusinessname,
scheduleADemo.Address,
scheduleADemo.City,
scheduleADemo.State,
scheduleADemo.ZipCode,
scheduleADemo.IheardofPrimeRxfrom,
scheduleADemo.Iamlookingtobuywithin,
scheduleADemo.Iwouldliketoseeademofor,
scheduleADemo.Message);
if (result)
{
return Json(new { success = true });
}
else
{
return Json(new { success = false });
}
}
Response on Postman over unknown field
Please give me your kind advice.

Nhibernate QueryOver how can I make this query use async?

For this new website I want to use async methods in NHibernate. I have this simple query using QueryOver API but I can't get this one to work with async.
It is a simple query with some where clauses that list all businesses. I want 20 of them each time I execute this.
Query:
BusinessListItem bli = null;
BusinessCategory bc = null;
Category c = null;
BusinessImage bi = null;
Image i = null;
var q = Session.QueryOver<Business>()
.JoinAlias(x => x.Categories, () => bc)
.JoinAlias(() => bc.Category, () => c)
.JoinAlias(x => x.Images, () => bi, JoinType.LeftOuterJoin)
.JoinAlias(() => bi.Image, () => i, JoinType.LeftOuterJoin)
.Where(() => bc.IsMain);
if (!string.IsNullOrEmpty(_name))
q.WhereRestrictionOn(x => x.Name).IsLike($"%{_name}%");
if (!string.IsNullOrEmpty(_streetName))
q.WhereRestrictionOn(x => x.StreetName).IsLike($"%{_streetName}%");
if (_categoryId != null)
q.Where(() => c.Id == _categoryId.Value);
if (_subCategoryIds != null)
q.WhereRestrictionOn(() => c.Id).IsIn(_subCategoryIds);
return q.Select(
Projections.Property<Business>(x => x.Id).WithAlias(() => bli.Id),
Projections.Property<Business>(x => x.Name).WithAlias(() => bli.Name),
Projections.Property("c.Name").WithAlias(() => bli.CategoryName),
Projections.Property("bi.Image").WithAlias(() => bli.Image)
)
.TransformUsing(Transformers.AliasToBean<BusinessListItem>())
.List<BusinessListItem>()
.OrderBy(x => x.Name)
.Skip(_skipCount)
.Take(20)
.ToList();
I know the method .ListAsync() exists but I cannot get it working together with the Skip, Take and OrderBy method.
Any help is much appreciated!
The solution to this question is :
var result = await q.Select(
Projections.Distinct(
Projections.Property<Business>(x => x.Id).WithAlias(() => bli.Id)
)
.TransformUsing(Transformers.AliasToBean<BusinessListItem>())
.OrderBy(x => x.Name).Asc
.Skip(_skipCount)
.Take(_takeCount)
.ListAsync<BusinessListItem>();
return result.ToList();
Thx to #DavidOsborne

check a condition before a ajax call back of form in drupal 7

I have written ajax callback on a textfield and it is called on blur event.
But before It going for ajax callback I want to check a condition that textfield not empty.
So I want,If textfield is not empty then the ajax callback is get called otherwise it should not get called.
Thanks in advance
form_example is my module name
Form control
$form['price_form']['item'] = array(
'#type' => 'textfield',
'#title' => 'Item Name?',
'#size' => 10,
'#maxlength' => 25,
'#id' => 'nameId',
'#required' => TRUE,
'#ajax' => array(
// #ajax has two required keys: callback and wrapper.
// 'callback' is a function that will be called when this element changes.
'callback' => 'form_example_simplest_callback',
'wrapper' => 'listDiv',
'effect' => 'fade',
),
'#autocomplete_path' => 'examples/form_example/item_name_autocomplete_callback',
);
JS Code
(function($){
$(document).ready(function(){
alert('Hi, Javascript successfully attached');
Drupal.behaviors.form_example = {
attach: function (context, settings) {
// Overwrite beforeSubmit
Drupal.ajax['nameId'].options.beforeSubmit = function (form_values, element, options) {
alert('dsf');
}
}
};
});
})(jQuery);
I am printing alert for testing.I tried by its name and by its id but not getting alert.I got below alert so js inclusion fine.
alert('Hi, Javascript successfully attached');
The ajax implementation in the form api lets you specify a 'beforeSubmit' handler that will be run before submission. According to this : http://malsup.com/jquery/form/#options-object if that function returns false the form won't be submitted.
You should be able to add a beforesubmit handler something like:
Drupal.behaviors.MyModule = {
attach: function (context, settings) {
// Overwrite beforeSubmit
Drupal.ajax['your_element'].options.beforeSubmit = function (form_values, element, options) {
// check the textfield isn't blank then return false;
}
}
};

ForeignKey column does not select value in Kendo-Grid

I have a grid with some columns where one of these columns is a foreignKey column.
I want to show all possible values for that column in a combobox. ViewData["States"] is an IList<State> where State has an Id field and a Name field.
To achieve that, I modified the template "GridForeignKey.cshtml" like the following:
#model object
#(
Html.Kendo().ComboBoxFor(m => m)
.BindTo((SelectList)ViewData[ViewData.TemplateInfo.GetFullHtmlFieldName("") +
"_Data"]).Filter(FilterType.Contains).Placeholder("Select...")
)
My View looks like this:
<div class="contentwrapper">
#{
ViewBag.Title = "Home Page";
Layout = "~/Views/Shared/_Layout.cshtml";
}
#(
Html.Kendo().Grid<CustomerModel>()
.Name("Grid")
.Columns(columns => {
columns.Bound(p => p.Name);
columns.ForeignKey(p => p.StateId, (IEnumerable)ViewData["States"], "Id", "Name");
columns.Bound(p => p.StreetAddress).Width(140);
columns.Bound(p => p.Zip).EditorTemplateName("Integer");
columns.Command(command => { command.Edit(); command.Destroy(); });//edit and delete buttons
})
.ToolBar(toolbar => toolbar.Create())//add button
.Editable(editable => editable.Mode(GridEditMode.InLine))//inline edit
.Pageable()
.Sortable()
.Scrollable()
.Filterable()
.DataSource(dataSource => dataSource
.Ajax()
.Events(events => events.Error("error_handler"))
.Model(model => {
model.Id(c => c.CustomerId);
model.Field(c => c.CustomerId).Editable(false);
model.Field(c => c.Zip).DefaultValue(4444);
}
)//id of customer
.Create(update => update.Action("EditingInline_Create", "Customer"))
.Read(read => read.Action("EditingInline_Read", "Customer"))
.Update(update => update.Action("EditingInline_Update", "Customer"))
.Destroy(update => update.Action("EditingInline_Destroy", "Customer"))
)
)
</div>
<script type="text/javascript">
function error_handler(e) {
if (e.errors) {
var message = "Errors:\n";
$.e`enter code here`ach(e.errors, function (key, value) {
if ('errors' in value) {
$.each(value.errors, function () {
message += this + "\n";
});
}
});
alert(message);//show error
}
}
</script>
Now my problems:
My Table does not show the selected value for "State".
When I edit a row, the combobox shows up and has all the desired values in it, but the value is not chosen. Instead it always shows the placeholder-text.
Before I had a complex object bound to my grid which had a field which was a complex type itself (State which contained the Id and Name attributes) but somehow kendo wouldnt let me bind it like p => p.State.Id. That's why I have flattened my model, and I now use the field StateId instead. Is it even possible to use a cascaded complex type like this?
What you have will not work. You need to pass the EditorTemplate the list in the EditorViewData and tell it which EditorTemplateName to use.
columns.ForeignKey(p => p.StateId, (IEnumerable)ViewData["States"], "Id", "Name")
.EditorViewData(new { statesList = ViewData["States"] })
.EditorTemplateName("GridForeignKey");
And GridForeignKey.cshtml like
#model int // Assuming Id is an int
#(Html.Kendo().ComboBoxFor(m => m)
.Placeholder("Select...")
.DataValueField("Id")
.DataTextField("Name")
.BindTo(ViewData["statesList"])
)
This might not be exactly right since I just did it off the top of my head. But it should get you in the right direction at least.
to achieve what you want you need to implement some client side scripts after you define the edit event in the Grid
.Events(events => events.Edit("onEdit"))
if your grid called **myGrid** then your script will be in this way
<script>
$(document).ready(function (e) {
var innerContent = $(".k-grid-delete").html().replace("Delete", "");
$(".k-grid-delete").html(innerContent);
});
function onEdit(e) {
$("#**myGrid** tbody [data-role=dropdownlist]").each(function () {
var ddl = $(this).data("kendoDropDownList");
if (ddl) {
ddl.options.optionLabel = "Select";
ddl.refresh();
ddl.value("");
}
})
}

KendoGrid - MVC - Entity - Identity column

I am building an MVC, Entities application with KendoGrids.
I have build this kendoGrid
#(Html.Kendo().Grid<ModelApp.Models.Tickets>()
.Name("ticketgrid")
.Columns(columns =>
{
columns.Bound(p => p.TicketID).Title("ID");
columns.ForeignKey(p => p.CustomerID, (System.Collections.IEnumerable)ViewData["customers"], "CustomerID", "CustomerName").Title("Customer");
columns.ForeignKey(p => p.AreaOfBusinessID, (System.Collections.IEnumerable)ViewData["areaofbusinesses"], "AreaOfBusinessID", "AreaOfBusiness1").Title("AreaOfBusiness");
columns.Bound(p => p.OccurredOn).Title("Occured").Format("{0:yyyy-MM-dd}");
columns.ForeignKey(p => p.SeverityID, (System.Collections.IEnumerable)ViewData["severities"], "SeverityID", "Severity1").Title("Severity");
columns.ForeignKey(p => p.AssigneeID, (System.Collections.IEnumerable)ViewData["assignees"], "AssigneeID", "AssigneeName").Title("Assignee");
columns.ForeignKey(p => p.TicketStatusID, (System.Collections.IEnumerable)ViewData["ticketstatuses"], "TicketStatusID", "TicketStatus1").Title("Status");
columns.Bound(p => p.UserID).Title("User");
columns.Bound(p => p.DateRegistered).Title("Registered").Format("{0:yyyy-MM-dd}");
})
.DataSource(dataSource =>
dataSource
.Ajax()
.Model(model => model.Id(p => p.TicketID))
.Read(read => read.Action("Index","Ticket"))
.Create(create => create.Action("Create", "Ticket"))
.Update(update => update.Action("Edit", "Ticket"))
//.Destroy(destroy => destroy.Action("Delete", "Ticket"))
)
.Pageable()
.Editable(editing => editing.Mode(GridEditMode.InCell))
.ToolBar(toolbar =>
{
toolbar.Create();
toolbar.Save();
})
.Navigatable()
.Selectable()
)
and I am facing 2 problems
1)The TicketID column is an identity column. When I select the Create button it fetches a zero. How can I make the Gid understand that it should not mess with this column and that the database will handle it?
Of course, no insert is being made anyway which takes me to the second question
2)The Edit does not post to database
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Edit([DataSourceRequest] DataSourceRequest request, IEnumerable<ModelApp.Models.Tickets> models)
{
if (models != null)
{
try
{
foreach (var updatedEntity in models)
{
var itemToUpdate = db.Tickets.Where(p => p.TicketID == updatedEntity.TicketID).FirstOrDefault();
if (itemToUpdate != null)
{
itemToUpdate.CustomerID = updatedEntity.CustomerID;
itemToUpdate.AreaOfBusinessID = updatedEntity.AreaOfBusinessID;
itemToUpdate.AssigneeID = updatedEntity.AssigneeID;
itemToUpdate.OccurredOn = updatedEntity.OccurredOn;
itemToUpdate.SeverityID = updatedEntity.SeverityID;
itemToUpdate.DateRegistered = updatedEntity.DateRegistered;
itemToUpdate.UserID = updatedEntity.UserID;
db.SaveChanges();
ModelState.Clear();
}
}
}
catch (Exception e)
{
db.add_exception_log(e.Message, "UPDATE RATES");
}
}
return Json(ModelState.ToDataSourceResult());
}
because models is null. Any clues why?
Thanx in advance
1) You should make the field non-editable inside of the Model configurator of the dataSource
model=>{
model.Fiedl(p=>p.TicketID).Editable(false);
}
2) You are not using batch editing to expect collection - change the signate to expect single record
public ActionResult Edit([DataSourceRequest] DataSourceRequest request, ModelApp.Models.Tickets model)

Resources