Disable validation on a #Html.TextBox in MVC - asp.net-mvc

I have a form in which I want to disable the required validation on one of the #Html.TextBox elements. The front end is as follows:
#model Models.NewUser
#using (Html.BeginForm("Register", "Account"))
{
<div class="field">
<span class="textOverField absolute em1-2" style="top:6px;left:4px;">Key</span>
#Html.TextBox("SchoolGroupKey", "", new { #class = "textField" })
</div>
<div class="field">
<span class="textOverField absolute em1-2" style="top:6px;left:4px;">Name</span>
#Html.TextBox("Names", "", new { #class = "textField" }) <div class="absolute validationMessage">#Html.ValidationMessageFor(u => u.Names)</div>
</div>
<div class="field">
<span class="textOverField absolute em1-2" style="top:6px;left:4px;">Last Name</span>
#Html.TextBox("LastNames", "", new { #class = "textField" }) <div class="absolute validationMessage">#Html.ValidationMessageFor(u => u.LastNames)</div>
</div>
<div class="em0-9" style="margin-bottom:20px;">
<input class="submitButton cursorHand" style="margin-top:10px;" type="submit" value="Registrarme" />
</div>
}
And the code for the model is as follows:
public class NewUser
{
[Required(ErrorMessage = "Name required")]
public string Names { get; set; }
[Required(ErrorMessage = "Last name required")]
public string LastNames { get; set; }
public System.Guid SchoolGroupKey { get; set; }
}
I'm guessing that the #Html.TextBox has a default validation even though I don't specify it. Is there someway to remove it?, I tried removing the html tags data-val-required and data-val, but still no results.
Thanks

Guid is a structure that behave as a simple type (just like int or DateTime). As such it is automaticly validated. If you want to make a workaround change your property type from Guid to nullable Guid?. Example:
public System.Guid? SchoolGroupKey { get; set; }
Of course you will have to change places when you use this property, to access the guid value throught Value property of nullable type.
If the mapping fails you will not get any validation errors then - just null value inside of your SchoolGroupKey property.

Related

Asp.net core MVC fetch image from DB based on the Category

I am sorry to bother with simple matters but i really cannot find a way out of this problem.
I am building a Gallery, which container different fields, one of those is Category.
Category Class is a public Enum, and i would like to retrieve all the images in the Database and display them in View based on my Category selection.
Here you can find the code that i wrote so far.
View:
<form method="get" asp-controller="Gallery" asp-action="index">
<div style="height:60px;" class="container">
<div class="row">
<div class="col-md-5">
<div class="row" style="padding-top:10px;">
<div class="col-md-5">
#Html.Editor("Name", new { htmlAttributes = new { #class = "form-control", placeholder = "Name..." } })
</div>
</div>
</div>
<div class="col-md-5">
<select class="custom-select form-control mr-sm-2" asp-items="Html.GetEnumSelectList<Category>()"></select>
</div>
<div class="col-md-1">
<div class="row" style="padding-top:10px; padding-right:20px;">
<button type="submit" name="submit" class="btn btn-success form-control" value="submit">
<i class="fas fa-search fa-1x"></i>
</button>
</div>
</div>
</div>
</div>
</form>
Controller:
public IActionResult Index(string Name, Category category)
{
var model = _galleryRepository.GetAllImages();
StringBuilder param = new StringBuilder();
param.Append("&Name=");
if (Name != null)
{
param.Append(Name);
}
if(Name != null)
{
model = _galleryRepository.SearchName(Name);
}
if(category != Category.All)
{
model = _galleryRepository.SearchCategory(category);
}
return View(model);
}
Model Category:
public enum Category
{
All,
Photography,
Portrait,
Nature
}
Model Gallery:
public class Gallery
{
public int Id { get; set; }
public int Like { get; set; }
public string Comment { get; set; }
[Required]
[MaxLength(40, ErrorMessage ="Name cannot exceed 40 characters")]
public string Name { get; set; }
[Required]
[MaxLength(100, ErrorMessage = "Description cannot exceed 100 characters")]
public string Description { get; set; }
[Required]
public Category Category { get; set; }
public string PhotoPath { get; set; }
}
I did Managed to create a search form based on the Name of the image and it works just fine. But when it come to retrieve the images based on the Category Selection, it does not work.
i used a breakpoint on the Controller on the If statment related to category, and i realized that the condition fires but the model inside no.
So i am asking to the expert for an explanation about how to fix it as it the first time that i work with Enum and retrieving datas based on Enum classes.
Thank you so much for your help and i hope i made clear my problem.
Change your view like below,then you could pass the selected item to category:
#model Gallery
<form method="get" asp-controller="Gallery" asp-action="index">
//...
<div class="col-md-5">
<select asp-for="Category" class="custom-select form-control mr-sm-2" asp-items="Html.GetEnumSelectList<Category>()"></select>
</div>
//...
</form>
The default model binder won't work with Enum types. Either you need to change the parameter to of type string and convert it to it's equivalent enum type before performing the comparisions OR provide your own implementation of model binder and override the default one. If I were you, I will go with the simplest solution like below,
public IActionResult Index(string Name, string selectedCategory)
{
var category = Enum.Parse(typeof(Category),selectedCategory,true);
var model = _galleryRepository.GetAllImages();
StringBuilder param = new StringBuilder();
param.Append("&Name=");
if (Name != null)
{
param.Append(Name);
}
if(Name != null)
{
model = _galleryRepository.SearchName(Name);
}
if(category != Category.All)
{
model = _galleryRepository.SearchCategory(category);
}
return View(model);
}

How manage a View (Validation and Binding etc) for Different models in a view in MVC

Consider a user can create a Sale advertising (Post model). but every advertising have different properties depend on its Group. Properties are not certain and can be added by admin with different constraints(Required. MinLength etc.)
I define a class like this:
public class Property
{
public int Id { get; set; }
public int Priority { get; set; }
[Required()]
public InputType Type { get; set; }
[Required()]
[MaxLength(150)]
public string Title { get; set; }
[Index(IsUnique=true)]
[Required()]
[MaxLength(100)]
public string Values { get; set; }
[MaxLength(100)]
public string Description { get; set; }
public ICollection<GroupProperty> GroupProperties { get; set; }
public ICollection<PostProperty> PostProperties { get; set; }
}
For example admin can add a model's car property to cars group. after that users must fill a model car field for advertisings in car group.
Create view for advertising is like this:
#model IEnumerable<Property>
<section>
<div class="container-fluid">
<div class="row">
<div class="col-md-6">
<h1>New Advertising</h1>
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
foreach (var item in Model)
{
#Html.EditorFor(m => item)
}
<button type="submit">hvah</button>
}
</div>
<div class="col-md-6">
</div>
</div>
</div>
</section>
Ah everything goes harder! I have a Editor template for Property class like this:
#model Property
#helper Helper(Property model)
{
switch (model.Type)
{
case WebSite.Models.DomainModels.InputType.NonNegative:
{
<div class="form-group">
<label for="#(model.Name)">#(model.Title)</label>
<span class="field-validation-valid text-danger" data-valmsg-for="#(model.Name)" data-valmsg-replace="true"></span>
<input class="form-control text-box single-line valid" data-val="true"
name="#(model.Name)" type="number" value="0"/>
</div>
return;
}
case WebSite.Models.DomainModels.InputType.RequiredShortString:
{
<div class="form-group">
<label for="#(model.Name)">#(model.Title)</label>
<span class="field-validation-valid text-danger" data-valmsg-for="#(model.Name)" data-valmsg-replace="true"></span>
<input class="form-control text-box single-line" data-val="true"
id="#(model.Name)" name="#(model.Name)" type="text" value="BB"/>
</div>
return;
}
}
}
#Helper(Model)
After all i have Client validation for properties. with hard code i can validate them in server side too. but new problem is Binding! if server side validation goes wrong i need to pass a model to view again. so i am think im doing this with a wrong way. can some one help me? maybe about how solve my problem or a better way to implement this? a simple way to use MVC validation On a complex model like this?
I think you want to create a class and validate ModelState. you can do it like-
Example:
You can pass your model state around like this:
public class MyClass{
public static void errorMessage(ModelStateDictionary ModelState) {
if (something) ModelState.AddModelError("", "Error Message");
}
}
Use in controller:
MyClass.errorMessage(ModelState);
If you need more information about modaestate validation outside then you can fiend more help from this link.

How to set value to a field in mongodb without using the field in view form

I want to set a value to Status property without using it in the view form
Here is the model class
public class NewsLetterModels
{
[BsonRepresentation(BsonType.ObjectId)]
public string Id { get; set; }
[Required]
public string NewsLetterName { get; set; }
[Required]
[DataType(DataType.EmailAddress, ErrorMessage = "E-mail is not valid")]
public string AssigneeEmailId { get; set; }
public string Status { get; set; }
public NewsLetterModels()
{
}
public NewsLetterModels(PostNewsLetter postNewsLetter)
{
NewsLetterName = postNewsLetter.NewsLetterName;
AssigneeEmailId = postNewsLetter.AssigneeEmailId;
Status = postNewsLetter.Status;
}
}
I don't want to set value to the field in viewform.In fact I don't want to show this field in the viewform. when I click on initiate News Letter,"Initiated" value should be set to the propert "Status". I am using MongoDb as database
Here is the View Page
<fieldset>
<legend>PostNewsLetter</legend>
<div class="editor-label">
#Html.LabelFor(model => model.NewsLetterName)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.NewsLetterName)
#Html.ValidationMessageFor(model => model.NewsLetterName)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.AssigneeEmailId)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.AssigneeEmailId)
#Html.ValidationMessageFor(model => model.AssigneeEmailId)
</div>
<p>
<input type="submit" value="Initiate NewsLetter" />
</p>
</fieldset>
Any help will be appreciable.
Are you referring to the 'Status' property?
You should set this in the controller or if you are using a repository layer you could in a save method insert values before saving to database.

Data annotation trigger validation on Get method

I have this viewmodel
public class ProductViewModel : BaseViewModel
{
public ProductViewModel()
{
Categories = new List<Categorie>
}
[Required(ErrorMessage = "*")]
public int Code{ get; set; }
[Required(ErrorMessage = "*")]
public string Description{ get; set; }
[Required(ErrorMessage = "*")]
public int CategorieId { get; set; }
public List<Categorie> Categories
}
My controller like this
[HttpGet]
public ActionResult Create(ProductViewModel model)
{
model.Categories = //method to populate the list
return View(model);
}
The problem is, as soon as the view is exhibited, the validation is fired.
Why this is happening?
Thanks in advance for any help.
Update
The view is like this
#using (Html.BeginForm("Create", "Product", FormMethod.Post, new { #class = "form-horizontal", #role = "form" }))
{
<div class="form-group">
<label for="Code" class="col-sm-2 control-label">Code*</label>
<div class="col-sm-2">
#Html.TextBoxFor(x => x.Code, new { #class = "form-control"})
</div>
</div>
<div class="form-group">
<label for="Description" class="col-sm-2 control-label">Desc*</label>
<div class="col-sm-2">
#Html.TextBoxFor(x => x.Description, new { #class = "form-control", maxlength = "50" })
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">Categorie*</label>
<div class="col-sm-4">
#Html.DropDownListFor(x => x.CategorieId, Model.Categories, "Choose...", new { #class = "form-control" })
</div>
</div>
You GET method has a parameter for your model, which means that the DefaultModelBinder initializes and instance of the model and sets its properties based on the route values. Since your not passing any values, all the property values are null because they all have the [Required] attribute, validation fails and ModelState errors are added which is why the errors are displayed when the view is first rendered.
You should not use a model as the parameter in a GET method. Apart from the ugly query string it creates, binding will fail for all properties which are complex objects and collections (look at you query string - it includes &Categories=System.Collections.Generic.List<Categorie> which of course fails and property Categories will be the default empty collection). In addition, you could easily exceed the query string limit and throw an exception.
If you need to pass values to the GET method, for example a value for Code, then you method should be
[HttpGet]
public ActionResult Create(int code)
{
ProductViewModel model = new ProductViewModel
{
Code = code,
Categories = //method to populate the list
};
return View(model);
}

Unobtrusive javascript adding data to #Html.HiddenFor

I have a hidden field on a form that is created in Razor using the #Html.HiddenFor helper:
#Html.HiddenFor(model => model.BidID, new { id="bidItemID" })
My View model looks like this:
public class BidEditVM
{
[Display(Name = "Bid ID")]
public int BidID { get; set; }
[StringLength(51)]
[Display(Name = "Customer Name")]
public string CustomerName { get; set; }
[StringLength(75)]
[Display(Name = "Bid Name")]
public string BidName { get; set; }
[Display(Name = "Amount")]
public decimal Amount { get; set; }
[Display(Name = "Time")]
public DateTime BidTime { get; set; }
}
When the HTML is rendered, unobtrusive javascript adds it's stuff to the hidden input field even though it will never require validation:
<input id="bidItemID" type="hidden" value="5198" name="BidID" data-val-required="The Bid ID field is required." data-val-number="The field Bid ID must be a number." data-val="true">
What's odder is that the message and validation it adds aren't even part of the view model for this partial view. The view looks like this:
#model AuctionAdmin.Models.ViewModels.BidEditVM
#using (Ajax.BeginForm("UpdateBid", new AjaxOptions { HttpMethod = "Post", UpdateTargetId = "modalBidInfo" }))
{
#Html.ValidationSummary(true)
#Html.HiddenFor(model => model.BidID, new { id="bidItemID" })
<fieldset>
<legend>Edit Bid</legend>
<div class="display-label">#Html.LabelFor(model => model.CustomerName)</div>
<div class="display-field">
#Html.DisplayFor(model => model.CustomerName)
</div>
<div class="display-label">#Html.LabelFor(model => model.BidName)</div>
<div class="display-field">
#Html.DisplayFor(model => model.BidName)
</div>
<div class="editor-label">#Html.LabelFor(model => model.Amount)</div>
<div class="editor-field">
#Html.EditorFor(model => model.Amount)
</div>
<div class="editor-label">#Html.LabelFor(model => model.BidTime)</div>
<div class="editor-field">
#Html.EditorFor(model => model.BidTime)
</div>
</fieldset>
}
Where is it getting this metadata from and how can I stop it?
It's marked as such since the type in the view model is an int.
It's adding the html due to this line:
#Html.HiddenFor(model => model.BidID, new { id="bidItemID" })
Why is it a problem that the extra attributes are present?
If it really is problematic, try changing the type of BidId to int? (a nullable int).

Resources