I have a view that allows user to add new items to a database.
The view looks like this:
#model News.Models.NewsEntry
#{
ViewBag.Title = "Create";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Create</h2>
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>NewsEntry</h4>
<hr />
#Html.ValidationSummary(true)
<div class="form-group">
#Html.LabelFor(model => model.title, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.title)
#Html.ValidationMessageFor(model => model.title)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.body, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.body)
#Html.ValidationMessageFor(model => model.body)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.category, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.category)
#Html.ValidationMessageFor(model => model.category)
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
Can I write some function (if sentance) inside my view that checks if the title input or the body input are empty and displays a message if they are.
My attempt so far:
EDIT:
In ASP MVC this should be done on the model, decorate the property using Required attribute
[Required(ErrorMessage = "Title is required!")]
public string title { get; set; }
[Required(ErrorMessage = "Body is required !")]
public string body { get; set; }
You will need to add following namespace:
using System.ComponentModel.DataAnnotations;
I created a project for you.
Try it its very simple:
Related
I have question in regarding how to add parameter see my codes below:
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Edit(Employee emp)
{
try
{
Employee updateEmp = _Context.Employee.FirstOrDefault(c => c.Idemployee == emp.Idemployee);
updateEmp.Address = emp.Address;
updateEmp.Age = emp.Age;
updateEmp.ContactNumber = emp.ContactNumber;
updateEmp.FullName = emp.FullName;
updateEmp.Gender = emp.Gender;
updateEmp.IsActive = emp.IsActive;
_Context.Employee.Update(updateEmp);
_Context.SaveChanges();
return RedirectToAction("Index");
}
catch (Exception)
{
throw;
}
}
What I am trying to do here is I am trying to extract the emp.Idemployee from the querystring but it couldn't and redirect me to the error null exception.
I am using a model to extract the details form the cshtml.
public IActionResult Edit(int id)
{
var editEmployee = _Context.Employee.FirstOrDefault(c => c.Idemployee == id);
return View(editEmployee);
}
I don't know whats wrong with it but all of the other information are extracted except for Idemployee.
#model Demo101.DAL.Entities.Models.Employee
#{
ViewBag.Title = "Edit Employee";
}
<h2>#ViewData["Title"]</h2>
<form asp-controller="Employee" asp-action="Edit" method="post" class="form-horizontal" role="form">
<div class="form-horizontal">
<div asp-validation-summary="All" class="text-danger"></div>
<!--FullName-->
<label asp-for="Idemployee" class="col-md-2 control-label"></label>
<div class="col-md-10">
#Html.LabelFor(model => model.Idemployee, new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.Idemployee)
</div>
<!--FullName-->
<label asp-for="FullName" class="col-md-2 control-label"></label>
<div class="col-md-10">
#Html.TextBoxFor(model => model.FullName, new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.FullName)
</div>
<!--Age-->
<label asp-for="Age" class="col-md-2 control-label"></label>
<div class="col-md-10">
#Html.TextBoxFor(model => model.Age, new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.Age)
</div>
<!--ContactNumber-->
<label asp-for="ContactNumber" class="col-md-2 control-label"></label>
<div class="col-md-10">
#Html.TextBoxFor(model => model.ContactNumber, new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.ContactNumber)
</div>
<!--Address-->
<label asp-for="Address" class="col-md-2 control-label"></label>
<div class="col-md-10">
#Html.TextBoxFor(model => model.Address, new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.Address)
</div>
<!--Gender-->
<label asp-for="Gender" class="col-md-2 control-label"></label>
<div class="col-md-10">
#Html.TextBoxFor(model => model.Gender, new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.Gender)
</div>
<!--IsActive-->
<label asp-for="IsActive" class="col-md-2 control-label"></label>
<div class="col-md-10">
#Html.CheckBoxFor(model => model.IsActive, new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.IsActive)
</div>
<!--Create Button-->
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Edit Employee" class="btn btn-default" />
</div>
</div>
</form>
Thanks!
Look at my code below, give this a go
<!--IdEmployee-->
<label asp-for="Idemployee" class="col-md-2 control-label"></label>
<div class="col-md-10">
#Html.LabelFor(model => model.Idemployee, new { #class = "form-control" })
#Html.HiddenFor(model => model.Idemployee)
#Html.ValidationMessageFor(model => model.Idemployee)
</div>
Your view does not contain any field with Employee value. You have label, you have validation message, but not value itself. Thus, you have no value in POST to server.
Add somewhere inside form:
#Html.HiddenFor(model => model.Idemployee)
I have the following view:
#model GRCWebApp.ViewModels.NewClubInterestsViewModel
#{
ViewBag.Title = "Add Club Interests";
}
<div class="col-md-10 col-offset-md-1">
<h2 class ="text-success">Add Club Interests for #Html.DisplayFor(model => model.Name)</h2>
</div>
#using (Html.BeginForm("NewInterests", "Club", FormMethod.Post))
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<hr />
<div class="row">
<div class="col-md-8">
<div class="well bs-component">
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
#Html.HiddenFor(x => Model.ClubId)
<div class="form-group">
<div class="col-md-10 col-md-offset-1">
<h3>Tick the areas your club is interested/runs events in</h3>
</div>
</div>
<div class="col-md-offset-1">
#for (int i = 0; i < Model.ClubTypeInterests.Count(); i++)
{
<div>
#Html.HiddenFor(x => Model.ClubTypeInterests[i].InterestId)
#Html.CheckBoxFor(x => Model.ClubTypeInterests[i].selected)
#Html.LabelFor(x => Model.ClubTypeInterests[i].InterestName, Model.ClubTypeInterests[i].InterestName)
</div>
}
</div>
<div class="form-group">
<div class="row">
<div class="col-md-offset-1 col-md-12">
<input type="submit" name="Submit" value="Next" class="btn btn-success btn-lg" /> to setup Online membership
<input type="submit" name="Submit" value="Complete" class="btn btn-warning btn-sm" /> to just provide online event entries
</div>
</div>
</div>
</div>
</div>
</div>
</div>
}
#using (Html.BeginForm("AddInterest", "Club"))
{
#Html.AntiForgeryToken()
<hr />
<div class="row">
<div class="col-md-8">
<div class="well bs-component">
<div class="form-group">
<div class="col-md-12 col-md-offset-1">
<h3>Not listed? - Add extras here</h3>
</div>
</div>
#Html.HiddenFor(model => model.ClubTypeId)
#Html.HiddenFor(model => model.ClubId)
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-inline">
<div class="form-group">
<div class="row col-md-offset-1 col-md-11">
<div class="col-md-4">
#Html.LabelFor(model => model.InterestName, htmlAttributes: new { #class = "control-label" })
#Html.EditorFor(model => model.InterestName, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.InterestName, "", new { #class = "text-danger" })
</div>
<div class="col-md-5">
#Html.LabelFor(model => model.Description, htmlAttributes: new { #class = "control-label" })
#Html.EditorFor(model => model.Description, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Description, "", new { #class = "text-danger" })
</div>
<input type="submit" value="Add" class="btn btn-info" style="margin-top: 22px" />
</div>
</div>
</div>
</div>
</div>
</div>
}
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
Overtime the page loads the Validation message shows for InterestName in the second form AddInterest.
The Get method for the whole form is:
[HttpGet]
public ActionResult NewInterests(NewClubInterestsViewModel model, int id)
{
//Find the Club and then pass its id to the ViewModel
var club = db.Clubs.Find(id);
//model.ClubId = club.ClubId ;
//Interests List
IEnumerable<Interest> allExistingInterests;
//Generate a list of the interests that apply to that type of club
using (ApplicationDbContext context = new ApplicationDbContext())
{
allExistingInterests = context.Interests
.Where(s => s.ClubTypeId == club.ClubTypeId)
.OrderBy(s => s.InterestName)
.ToList();
}
IEnumerable<int> clubInterestIds = club.ClubInterests.Select(x => x.InterestId).ToList();
//Generate the ViewModel with the appropriate Interests
var viewModel = new NewClubInterestsViewModel
{
ClubId = club.ClubId,
Name = club.Name,
ClubTypeId = club.ClubTypeId,
ClubTypeInterests =
allExistingInterests.Select(
x => new ClubInterestsViewModel { InterestId = x.InterestId, InterestName = x.InterestName, selected = clubInterestIds.Contains(x.InterestId) }).ToArray()
};
return View(viewModel);
}
What do I need to do to stop the validation message showing on load?
Remove the NewClubInterestsViewModel model parameter from your GET method. It should be just
public ActionResult NewInterests(int id)
The first step in the model binding process is that instances of your parameters are initialized and then its properties are set based on form values, route values, query string values etc. In your case there are no values to set, so the properties of your model are their defaults, but because you have validation attributes on your properties, validation fails and errors are added to ModelState which are then displayed in the view.
I am creating a page in Asp.Net MVC where a user can upload a file, along with details about the file from textboxes.
For this I use a viewmodel, and a very simple method configuration. The page is populated correctly by the [Get] Method, and the user can choose the file and enter the details, but once the 'Submit' button is clicked, and the [Post] method is called, the viewmodel is completely null.
I have done my research on this and have tried:
adding enctype="multipart/form-data"
simply using the file as a separate parameter
To no avail.
Here is my controller methods:
public ActionResult FileComment(int id)
{
//set up [get] view
return View("FileComment", obj);
}
//THIS METHOD's VIEWMODEL ALWAYS NULL
[HttpPost]
public ActionResult FileComment(CalibrationCommentViewModel file)
{
//save file to database
return View("Edit", new { id = file.id });
}
Here is part of my view:
#using (Html.BeginForm("FileComment", "Calibration", FormMethod.Post, new { enctype = "multipart/form-data", #data_ajax = "false" }))
{
#Html.HiddenFor(m => m.ID)
<div class="container">
<h4>Add File for #Model.ID</h4>
<hr />
<div class="row">
<div class="col-md-1">g
#Html.LabelFor(model => model.file, htmlAttributes: new { #class = "control-label" })
</div>
<div class="col-md-2">
#Html.TextBoxFor(model => model.file, new { type = "file" })
</div>
<div class="col-md-9"></div>
</div>
<br />
<div class="row">
<div class="col-md-1">
#Html.LabelFor(model => model.attachmentType, htmlAttributes: new { #class = "control-label" })
</div>
<div class="col-md-2">
#Html.DropDownListFor(model => model.attachmentType, Model.attachTypeList, new { #class = "form-control" })
</div>
<div class="col-md-9"></div>
</div>
<br />
<div class="row">
<div class="col-md-1">
#Html.LabelFor(model => model.Date, htmlAttributes: new { #class = "control-label" })
</div>
<div class="col-md-2">
#Html.EditorFor(model => model.Date)
</div>
<div class="col-md-9"></div>
</div>
<br />
<div class="row">
<div class="col-md-1">
#Html.LabelFor(model => model.description, htmlAttributes: new { #class = "control-label" })
</div>
<div class="col-md-2">
#Html.TextAreaFor(model => model.description, new { cols=35, #rows=3})
</div>
<div class="col-md-9"></div>
</div>
<br />
<div class="row">
<div class="col-md-1"></div>
<div class="col-md-2">
<button type="submit" onclick="JavascriptFunction()">Add to #Model.ID</button>
</div>
<div class="col-md-9"></div>
</div>
</div>
}
Change
public ActionResult FileComment(CalibrationCommentViewModel file)
to
public ActionResult FileComment(CalibrationCommentViewModel model)
your view has no reference to view model at the top the view something like this
#model Nameofyourproject.Models.CalibrationCommentViewModel
_getProductReviews.cshtml:
I'm calling my partial view like this:
<p>#Html.Partial("_CreateR");</p>
_CreateR.cshtml:
This code is auto generated by the controller:
#model Commerce.Domain.Entites.t_review
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>t_review</h4>
<hr />
#Html.ValidationSummary(true)
<div class="form-group">
#Html.LabelFor(model => model.text, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.text)
#Html.ValidationMessageFor(model => model.text)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.title, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.title)
#Html.ValidationMessageFor(model => model.title)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.customer_id, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.customer_id)
#Html.ValidationMessageFor(model => model.customer_id)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.product_fk, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.product_fk)
#Html.ValidationMessageFor(model => model.product_fk)
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}
ProductController:
// GET: /Product/Create
public ActionResult Create()
{
return View();
}
//
// POST: /Product/Create
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "id,text,title,customer_id,product_fk")] t_review review)
{
if (ModelState.IsValid)
{
prose.CreateReview(review);
return RedirectToAction("Index");
}
return View(review);
}
When I use a simple view with actionlink it works but when I try to use partial View shows this msg
The model item passed into the dictionary is of type 'System.Collections.Generic.List`1[Commerce.Domain.Entites.t_review]', but this dictionary requires a model item of type 'Commerce.Domain.Entites.t_review'.
Html.Partial renders a view without calling the Controller first.
Html.Action calls a Controller Action which can return like everything: a view, a partial view, json, etc.
As a general guideline, you should use Html.Partial only when you want to display static content or when you have access to the model required. For everything else, like wen you want to return more data from the server, use Html.Action.
I have an entity called Person who has a list of colours. The colours have a name and active field. When I edit a person I want to be able to edit the colours attached to them. I'm having trouble doing this in the razor view - as I am getting errors.
#model InterviewTest.Domain.Entities.Person
#{
ViewBag.Title = "Edit";
}
<h2>Edit</h2>
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Person</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
#Html.HiddenFor(model => model.PersonId)
<div class="form-group">
#Html.LabelFor(model => model.IsAuthorised, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
<div class="checkbox">
#Html.EditorFor(model => model.IsAuthorised)
#Html.ValidationMessageFor(model => model.IsAuthorised, "", new { #class = "text-danger" })
</div>
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.IsEnabled, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
<div class="checkbox">
#Html.EditorFor(model => model.IsEnabled)
#Html.ValidationMessageFor(model => model.IsEnabled, "", new { #class = "text-danger" })
</div>
</div>
</div>
I'm trying to attempt it doing this - but not working.
<h2>Favourite Colours</h2>
#foreach(var item in Model.Colours)
{
<div class="form-group">
#Html.LabelFor(item.Name, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
<div class="checkbox">
#Html.EditorFor(item.IsEnabled)
#Html.ValidationMessageFor(model => model.IsEnabled, "", new { #class = "text-danger" })
</div>
</div>
</div>
}
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Save" class="btn btn-default" />
</div>
</div>
</div>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
Syntax error. It is incomplete in the following div
<div class="checkbox">
#Html.EditorFor**(item.)**
#Html.ValidationMessageFor(model => model.IsEnabled, "", new { #class = "text-danger" })
</div>
Rather use item.Name
Please make sure whether the properties in Colour class is all public and whether the isEnabled property exists.
Looking at your code it seems like IsAuthorised and IsEnabled property is available for the Model i.e the Person entity.
But in the forearch item in Model.Colours you are trying to use IsEnabled for an item i.e in this case it is Colour entity.
Are you missing the lambda expression in the LabelFor and EditorFor? You used it everywhere else.
#Html.EditorFor(model => model.IsAuthorised)