How to make KendoNumericTextBox wrapper to render Required model attribute? - kendo-asp.net-mvc

I'm in an MVC6 project and trying to add a simple Kendo NumericTextBox widget using provided HtmlHelpers.
My model looks like this:
public class DataViewModel
{
[Required]
public double MyNumber {Get; Set;}
....
}
My view:
...
#(Html.Kendo.NumericTextBoxFor(m=>m.MyNumber)
...
)
But Input tag generated from this code doesn't include the "required" attribute so client validator doesn't check for completness.
Any ideas on how to get the required validation working in client?

I experienced the same problem and asked Telerik people about this. Their answer is that MVC6 is still in pre-release and changing a lot, so they will wait to production release to check for this issues.
Meanwhile, a workaround would be this:
#(Html.Kendo.NumericTextBoxFor(m=>m.MyNumber)
.HtmlAttributes(new {required="required"})
...
)

Related

How to add model to PredictionEnginePool in middleware (ML.NET)?

I'm using ML.NET in an ASP.NET Core application, and I am using the following code in Startup:
var builder = services.AddPredictionEnginePool<Foo, Bar>();
if (File.Exists("model.zip"))
{
builder.FromFile(String.Empty, "model.zip", true);
}
If model.zip doesn't exist, I create it later in the middleware. How do I add it to the PredictionEnginePool that is injected?
There are no options to load a model via PredictionEnginePool, and instantiating or injecting a PredictionEnginePoolBuilder isn't an option as it requires IServiceCollection (so must be configured during Startup.ConfigureServices).
The only option I can see at the moment is to set a flag if the file doesn't exist at startup, and then restart the service after model.zip is created in the middleware later on (using IApplicationLifetime.StopApplication), but I really don't like this as an option.
PredictionEnginePool is designed in such a way that you can write your own ModelLoader implementation. Out of the box, Microsoft.Extensions.ML has 2 loaders, File and Uri. When those don't meet your needs, you can drop down and write your own.
See https://github.com/dotnet/machinelearning-samples/pull/560 which changes one of the dotnet/machine-learning samples to use an "in-memory" model loader, it doesn't get the model from a file or a Uri. You can follow the same pattern and write whatever code you need to get your model.
public class InMemoryModelLoader : ModelLoader
{
private readonly ITransformer _model;
public InMemoryModelLoader(ITransformer model)
{
_model = model;
}
public override ITransformer GetModel() => _model;
public override IChangeToken GetReloadToken() =>
// This IChangeToken will never notify a change.
new CancellationChangeToken(CancellationToken.None);
}
And then in Startup.cs
services.AddPredictionEnginePool<ImageInputData, ImageLabelPredictions>();
services.AddOptions<PredictionEnginePoolOptions<ImageInputData, ImageLabelPredictions>>()
.Configure(options =>
{
options.ModelLoader = new InMemoryModelLoader(_mlnetModel);
});

Map two templates for different sites

We are developing a multisite sitecore solution where each sites can have have their own News as well as able to display the combined news from other Sites.
Problem:
Each site have their unique News requirements where 90% of the template fields matches but rest 10% are different.
For example, Site-A has news template with Authors drop down list where Author List are authored on Configuration Node. Where as Site-B has news template where Author is a FREE TEXT Field.
Therefore, when Glass Mapper automatically tries to Map Authors field it fails for Free Text one.
Solution:
This can be resolved either by creating a Author as drop down on all Sites but Product owners don't want this.
The other solution is manual mapping of news fields from both sources or use AUTOMAP etc.
Desired Solution:
Glassmapper automatically resolves and populates the Author Text Field or Drop Down Field on the fly.
Is above possible?
Thank you.
I would solve this by "fluent configuration", http://glass.lu/Mapper/Sc/Tutorials/Tutorial8.aspx.
Combined with the new Delegate feature added to the Glass Mapper recently.
The Delegate feature was originally introduced and described here: http://cardinalcore.co.uk/2014/07/02/controlling-glass-fields-from-your-own-code/
Nuget package for the Delegate feature: https://www.nuget.org/packages/Cardinal.Glass.Extensions.Mapping/
You can use Infer types as follows:
public interface IBaseNews
{
string Author {get; set;}
//List all other shared fields below
}
[SitecoreType(TemplateId="....", AutoMap = true)]
public class NewsSiteA : IBaseNews
{
[SitecoreField]
public string Author {get; set;}
//List all fields which are unique for SiteA
}
[SitecoreType(TemplateId="....", AutoMap = true)]
public class NewsSiteB : IBaseNews
{
[SitecoreField]
public string Author {get; set;}
//List all fields which are unique for SiteB
}
Now, Your code should be:
IBaseNews newsClass = NewsItem.GlassCast<IBaseNews>(true,true);
//You can use Author property now
Firstly, I would recommend updating to the latest version of Glass for many other reasons including the delegate feature.
From the infer type example in the comment - you shouldn't use GlassCast, use CreateType(Item item) from the sitecore service / context. If you adopt the version with Delegate in, there is now an official Cast(Item item) on the sitecore service instead.
Also the example there uses a would not solve the difference in type. Delegate would make this very easy. Remember with delegate that there is no lazy loading, this shouldn't matter in this case.
public interface INews
{
// All my other fields
string Author { get; set; }
}
The fluent configuration would be something like (to be done in GlassScCustom)
SitecoreType<INews> = new SitecoreType<INews>();
sitecoreType.Delegate(y => y.Author).GetValue(GetAuthor);
fluentConfig.Add(sitecoreType);
private string GetAuthor(SitecoreDataMappingContext arg)
{
Item item = arg.Item;
if(item.TemplateID == <templateid>)
{
// return the value from the drop link
}
return item["Authors"];
}

Make regular expression field optional which is displayed as mandatory field in MVC 4

I'm working on ASP.NET MVC 4. I'm using Data Annotations in model for validation.
There is one field name Mobile and validating using regular expression like below.
[RegularExpression(#"[0-9]{10}", ErrorMessage = "Mobile Number is Not Valid")]
public string Mobile { get; set; }
As per the application requirement above field is not mandatory but need to validate Mobile number if user insert it.
My problem is that when I submit form it displays "Mobile field is required." but the mobile field is not decorate with [Required] attribute. So How it display as required?
What could be the reason?
How to solve it?
In your project, there is a folder "views" where you probably created your view with your needed controls.
there should be something like:
#Html.LabelFor(m => m.Mobile)<br />
#Html.TextBoxFor(m => m.Mobile)<br />
in order to make the regularExpression work.
If you already did this, another problem could be your model.
At the top of your view you should add your model by:
#model yourModelName
As you did not post any code in you controller, Index is assumed as action of your controller and MyModel is assumed as model.
Try the following code in your controller:
public ActionResult Index(MyModel model)
{
//This will check if `Mobile` is empty and remove the Mobile from validation if the field is empty
if (collection.Get("Mobile") == "") //Mobile is the name of the Mobile number field in view
{
ModelState.Remove("Mobile");
}
if(ModelState.IsValid){
//do something
}
else{
return View(model);
}
}
Hope it helps
You can do it very easily using following simple jQuery..
//Remove Required field validation on pin and mobile number
$(document).ready(function () {
$("#Mobile").removeAttr("data-val");
});
Pls try and let me us know if that works for you or not.
Thanks

Play Framework Template list only top 5

In Play framework how do I list only a certain number of object from database instead of all.
Suppose that I have this Post class that has a #OneToMany relation with Comments just like this
public class Post extends Model {
#ManyToOne
public User user;
public String name;
public String description;
public String image;
public Date created_date;
#OneToMany(mappedBy="post", cascade=CascadeType.ALL)
public List<Comment> comments;
....
}
How do I only list top 5 comments for each post at the template? I've done this, but it shows all comments
#{list items:post.comments, as:'comment'}
<p>${comment.comment}</p>
#{/list}
Thanks
You can just use standard Java to get the sub list
#{list items:post.comments.subList(0,5), as:'comment'}
<p>${comment.comment}</p>
#{/list}
The above will return an array index out of bounds if there are less than 5 comments though, so you can either put some more logic in the template (as below), or you could create a getter method in your Post model that gets the top5 comments, and just call this instead (which is probably the cleaner and preferred option.
The extra logic in the template would look like
#{list items:post.comments.subList(0, Math.min(5, post.comments.size())), as:'comment'}
<p>${comment.comment}</p>
#{/list}
If you agree that this is too much logic in your view, and want to encapsulate it in your Model, you could do the following.
The extra logic in your view may look like
public List<Comment> getTop5() {
return comments.subList(0, Math.min(5, comments.size());
}
And then your controller would be
#{list items:post.top5, as:'comment'}
<p>${comment.comment}</p>
#{/list}

How can I set a RegularExpression data annotation's regular expression argument at runtime?

We manage several ASP.NET MVC client web sites, which all use a data annotation like the following to validate customer email addresses (I haven't included the regex here, for readability):
[Required(ErrorMessage="Email is required")]
[RegularExpression(#"MYREGEX", ErrorMessage = "Email address is not valid")]
public string Email { get; set; }
What I would like to do is to centralise this regular expression, so that if we make a change to it, all of the sites immediately pick it up and we don't have to manually change it in each one.
The problem is that the regex argument of the data annotation must be a constant, so I cannot assign a value I've retrieved from a config file or database at runtime (which was my first thought).
Can anyone help me with a clever solution to this—or failing that, an alternative approach which will work to achieve the same goal? Or does this just require us to write a specialist custom validation attribute which will accept non-constant values?
The easiest way is to write a custom ValidationAttribute that inherits from RegularExpressionAttribute, so something like:
public class EmailAttribute : RegularExpressionAttribute
{
public EmailAttribute()
: base(GetRegex())
{ }
private static string GetRegex()
{
// TODO: Go off and get your RegEx here
return #"^[\w-]+(\.[\w-]+)*#([a-z0-9-]+(\.[a-z0-9-]+)*?\.[a-z]{2,6}|(\d{1,3}\.){3}\d{1,3})(:\d{4})?$";
}
}
That way, you still maintain use of the built in Regex validation but you can customise it. You'd just simply use it like:
[Email(ErrorMessage = "Please use a valid email address")]
Lastly, to get to client side validation to work, you would simply add the following in your Application_Start method within Global.asax, to tell MVC to use the normal regular expression validation for this validator:
DataAnnotationsModelValidatorProvider.RegisterAdapter(typeof(EmailAttribute), typeof(RegularExpressionAttributeAdapter));
Checkout ScotGu's [Email] attribute (Step 4: Creating a Custom [Email] Validation Attribute).
Do you really want to put the regex in database/config file, or do you just want to centralise them? If you just want to put the regex together, you can just define and use constants like
public class ValidationRegularExpressions {
public const string Regex1 = "...";
public const string Regex2 = "...";
}
Maybe you want to manage the regexes in external files, you can write a MSBuild task to do the replacement when you build for production.
If you REALLY want to change the validation regex at runtime, define your own ValidationAttribute, like
[RegexByKey("MyKey", ErrorMessage = "Email address is not valid")]
public string Email { get; set; }
It's just a piece of code to write:
public class RegexByKeyAttribute : ValidationAttribute {
public RegexByKey(string key) {
...
}
// override some methods
public override bool IsValid(object value) {
...
}
}
Or even just:
public class RegexByKeyAttribute : RegularExpressionAttribute {
public RegexByKey(string key) : base(LoadRegex(key)) { }
// Be careful to cache the regex is this operation is expensive.
private static string LoadRegex(string key) { ... }
}
Hope it's helpful: http://msdn.microsoft.com/en-us/library/cc668224.aspx
Why not just write you own ValidationAttribute?
http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.validationattribute.aspx
Then you can configure that thing to pull the regex from a registry setting... config file... database... etc... etc..
How to: Customize Data Field Validation in the Data Model Using Custom