Here is my Model
public partial class Asset
{
public long ID { get; set; }
[RegularExpression("^[0-9]*$", ErrorMessage = "Title must be numeric")]
public string Title { get; set; }
public string Description { get; set; }
}
and in my view
<div class="Content-inner-pages">
<div class="TopHeading TopHeading2">
<h2>Assets</h2>
@* @Html.ActionLink("Create", "Create")*@
<a class="CreateBtn AssetsBtn" href="Javascript:void(0);" onclick="javascript: HideUpdateButton();">Add Asset</a>
<div class="clearfix"></div>
</div>
<input type="hidden" id="hdnIsNew" value="1" />
<input type="hidden" id="hdnRecId" />
<!-- Slide Popup panel -->
<div class="cd-panel from-right AddAssetForm">
<header class="cd-panel-header">
<h3>Add Asset</h3>
<a href="javascript:void(0);" onclick="javascript: DisplayClear();" class="cd-panel-close">Close</a>
</header>
<div class="cd-panel-container">
<div class="cd-panel-content">
<!-- Add Reminder -->
<div class="form-horizontal form-details popup-box">
@using (Html.BeginForm("AssetsPage", "SuperAdmin", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<div class="form-group">
<label class="col-md-5 control-label">
Asset Title
</label>
@Html.TextArea("ID", "", new { @class = "form-control", @id = "ID", @style = "display:none;" })
<div class="col-md-7">
@Html.TextBox("Title", "", new { @class = "form-control", @id = "Title", required = "required" })
@Html.ValidationMessage("Title", "*")
</div>
</div>
<div class="form-group">
<label class="col-md-5 control-label">Description</label>
<div class="col-md-7">
@Html.TextArea("Description", "", new { @class = "form-control", @id = "Description", required = "required" })
@Html.ValidationMessage("Description", "*")
</div>
</div>
<div class="form-group">
<label class="col-md-5 control-label">Attachment</label>
<div class="col-md-7">
<input type="file" name="file" id="filena" class="custom-file-input" required="required">
@Html.ValidationMessage("file", "*")
</div>
</div>
<div class="form-group">
<div class="col-md-7 col-md-offset-5">
<input type="submit" id="SaveBtn" value="Save" name="actiontype" class="btn-class btn-success">
<input type="submit" id="UpdateBtn" value="Update" name="actiontype" class="btn-class btn-success">
</div>
</div>
}
</div><!-- End Add Reminder -->
</div> <!-- cd-panel-content -->
</div> <!-- cd-panel-container -->
</div> <!-- cd-panel -->
<div class="box">
<div class="box-content Custom-DataTable">
<table id="AdministationAssets" class="table table-hover dt-responsive CustomDatable AdministationAssetsTable" cellspacing="0" width="100%">
<thead>
<tr>
<th style="width:5%;">Assets</th>
<th style="width:15%;">
@Html.DisplayNameFor(model => model.Title)
</th>
<th style="width:50%;">
@Html.DisplayNameFor(model => model.Description)
</th>
<th style="width:8%;">Options</th>
</tr>
</thead>
<tbody>
@foreach (var item in Model)
{
<tr>
<td id="target" class="">
@{
switch (item.Extenstion.ToLower())
{
case "doc":
<i class="fa fa-file-word-o text-primary AssetIcon"></i>
break;
case "docx":
<i class="fa fa-file-word-o text-primary AssetIcon"></i>
break;
case "xls":
<i class="fa fa-file-excel-o text-success AssetIcon"></i>
break;
case "xlsx":
<i class="fa fa-file-excel-o text-success AssetIcon"></i>
break;
case "ppt":
<i class="fa fa-file-powerpoint-o text-danger AssetIcon"></i>
break;
case "jpg":
<i class="fa fa-file-photo-o text-warning AssetIcon"></i>
break;
case "png":
<i class="fa fa-file-photo-o text-warning AssetIcon"></i>
break;
case "pdf":
<i class="fa fa-file-pdf-o text-danger AssetIcon"></i>
break;
case "zip":
<i class="fa fa-file-archive-o text-muted AssetIcon"></i>
break;
case "htm":
<i class="fa fa-file-code-o text-info AssetIcon"></i>
break;
case "txt":
<i class="fa fa-file-text-o text-info AssetIcon"></i>
break;
case "mov":
<i class="fa fa-file-movie-o text-warning AssetIcon"></i>
break;
case "mp3":
<i class="fa fa-file-audio-o text-warning AssetIcon"></i>
break;
default:
<i class="fa fa-file AssetIcon"></i>
break;
}
}
</td>
<td>
@Html.DisplayFor(modelItem => item.Title)
</td>
<td>
@Html.DisplayFor(modelItem => item.Description)
</td>
<td>
@Html.ActionLink("Download", "DownloadAsset", new { id = item.ID }, new { @class = "ActionInvoice" })
@Html.ActionLink("Edit", "AddEditRecord", new { id = item.ID }, new { @class = "ActionEdit AssetEdit", onclick = "javascript:GetEditDetails(" + item.ID + ")" })
@Html.ActionLink("Delete", "AssetDelete", new { id = item.ID }, new { @class = "ActionDelete", onclick = "return confirm('Are You Sure delete this record?');", })
</td>
</tr>
}
</tbody>
</table>
</div>
</div>
the thing is validation is happening for Required field and Regular expression numeric number but error message is not being display for Regular Expression as i want to show that error: Title must be numeric. please let me know where i am doing wrong here while applying validation.
The reason you do not get any validation is that the model in your view is
@model IEnumerable<Asset>
and you generating inputs for properties which do not exist in the model
@Html.TextBox("Title")
creates <input name="Title" id = "Title" value="" />
but IEnumerable<Asset>
does not have a property named Title
so no data-val-*
attributes are generated and therefore no rules are added to the $.validator
to generate client side validation.
Note that the only validation your getting is as a result of adding the new { required = "required" }
attribute which is HTML-5 validation only and will not give you the essential server side validation.
You can solve this by creating a view model
public class AssetVM
{
public long? ID { get; set; }
[Required(ErrorMessage = "Please enter a title")]
[RegularExpression("^[0-9]*$", ErrorMessage = "Title must be numeric")]
public string Title { get; set; }
[Required(ErrorMessage = "Please enter a description")]
public string Description { get; set; }
public IEnumerable<Asset> Assets { get; set; }
}
and in the controller, initialize a new AssetVM
and populate the Assets
property with the collection and return it to the view.
var model = new AssetVM()
{
Assets = .... // your query
};
return View(model);
and in the view
@model AssestVM
....
@using (Html.BeginForm("AssetsPage", "SuperAdmin", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
@Html.HiddenFor(m => m.ID)
....
@Html.TextBoxFor(m => m.Title, new { @class = "form-control"})
@Html.ValidationMessage(m => m.Title)
....
}
....
@foreach(var asset in Model.Assets)
{
// build your table
}
Another alternative would be to keep your existing @model IEnumerable<Asset>
and create a partial view that returns your form for an Asset
and in the main view and then use @Html.Partial("_Asset", new Asset() )
to generate the form in the main view.
Side notes:
@Html.HiddenFor()
to generate the input for the ID
, not a
textarea styled as hiddennew { id = "###" }
- the HtmlHelper
methods already add the id
attribute and your just overwriting the
value with the same valuenew { required = "required" }
attribute Use
Unobtrusive Javascript rather than polluting your markup with
behaviorpublic HttpPostedFileBase File { get; set; }
and in the form @Html.TextBoxFor(m => m.File, new { type = "file"
})
. You should also consider a property for the file's display name
so that can be output in the viewswitch
statement in the view (set in in the
controller)For a working example of how this could be implemented, refer to this DotNetFiddle, although in your case, because you are also uploading a file, you would need to post the form using FormData
as described in this answer