I have ASP.NET MVC application and I am failing to Server-side and client-side validation for partial page. In the start of my application there is login page which validating correctly. so if I press submit with no values in form, app don't show any error messages
model class
public class CreateFunctionNavigation_SP_Map
{
public CreateFunctionNavigation_SP_Map()
{
}
//Function Table
[StringLength(250)]
[Required(ErrorMessage = "Required Function Title")]
[Display(Name = "Function Title")]
public string FunctionName { get; set; }
[Required(ErrorMessage = "Required Function Hierarchy; i.e Where Function Exists In Hierarchy Tree \n Top-Level Start From 1 ")]
[Display(Name = "Function Hierarchy Level")]
public int FunctionHierarchy_Level { get; set; }
//Controller Table
[StringLength(250)]
[Required(ErrorMessage = "Required Controller Title")]
[Display(Name = "Controller Title")]
public string ControllerName { get; set; }
//Action Table
[StringLength(250)]
[Required(ErrorMessage = "Required Action Title")]
[Display(Name = "Action Title")]
public string ActionName { get; set; }
// Hierarchy Table
[Required(ErrorMessage = "Required Function Parent - Child Relation ID \n Put 0 In Case Given Function doesn't Have Any Parent Function ")]
[Display(Name = "Function Parent's FunctionID")]
public int Function_ParentsFunctionID { get; set; }
}
controller method
#region CreateNewFunctionNavigation
[HttpGet]
public ActionResult CreateNewFunctionNavigation()
{
return PartialView("CreateNewNavigation_Partial");
}
#endregion
[HttpPost]
public ActionResult CreateNewFunctionNavigation(CreateFunctionNavigation_SP_Map obj )
{
try
{
if(ModelState.IsValid)
{
_FN_Services_a2.CreateFunctionNavigation(obj);
}
}
catch (DataException ex)
{
ModelState.AddModelError("", "Unable To Create New Function Navigation" + ex);
}
return RedirectToAction("SystemCoreHome");
} //end
view
#model App.DAL.Model.CreateFunctionNavigation_SP_Map
<div class="_Form_Block">
#using (Html.BeginForm("CreateNewFunctionNavigation", "SystemCore", FormMethod.Post, new { id = "NewFunctionNavigationForm" }))
{
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
<div class="form-group">
#Html.LabelFor(#model => #model.FunctionName, new { #class = "control-label col-md-2" })
<div class="form-group">
#Html.EditorFor(#model => #model.FunctionName)
#Html.ValidationMessageFor(#model => #model.FunctionName)
</div>
</div>
<div class="form-group">
#Html.LabelFor(#model => #model.FunctionHierarchy_Level, new { #class = "control-label col-md-2" })
<div class="form-group">
#Html.EditorFor(#model => #model.FunctionHierarchy_Level)
#Html.ValidationMessageFor(#model => #model.FunctionHierarchy_Level)
</div>
</div>
<div class="form-group">
#Html.LabelFor(#model => #model.ControllerName, new { #class = "control-label col-md-2" })
<div class="form-group">
#Html.EditorFor(#model => #model.ControllerName)
#Html.ValidationMessageFor(#model => #model.ControllerName)
</div>
</div>
<div class="form-group">
#Html.LabelFor(#model => #model.ActionName, new { #class = "control-label col-md-2" })
<div class="form-group">
#Html.EditorFor(#model => #model.ActionName)
#Html.ValidationMessageFor(#model => #model.ActionName)
</div>
</div>
<div class="form-group">
#Html.LabelFor(#model => #model.Function_ParentsFunctionID, new { #class = "control-label col-md-2" })
<div class="form-group">
#Html.EditorFor(#model => #model.Function_ParentsFunctionID)
#Html.ValidationMessageFor(#model => #model.Function_ParentsFunctionID)
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default _formButton" />
<input type="button" value="Cancel" class="btn btn-default _formButton" onclick="CancelPage();" />
</div>
</div>
}
</div> <!--End _Form_Block-->
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
instead of
return RedirectToAction("SystemCoreHome");
use
return PartialView("CreateNewNavigation_Partial", obj);
Ajax Form
#using (Ajax.BeginForm(new AjaxOptions { UpdateTargetId = "TargetID" }))
{
...
}
<div class="_Form_Block" id="TargetID">
</div>
You need to handle this case.
Presently you are not doing anything in the event that the ModelState is invalid. Try the following:
public ActionResult CreateNewFunctionNavigation(CreateFunctionNavigation_SP_Map obj)
{
if (!ModelState.IsValid)
{
return View(obj);
}
// rest of method here
if(ModelState.IsValid)
{
_FN_Services_a2.CreateFunctionNavigation(obj);
}
else
{
return View();
}
Should do the trick.
Related
Whenever i am clicking on submit after uploading file, it gets returned null, i have used all the necessary conditions required for upload file but still getting the issue, i have seen all the answers in stack overflow , i have used enctype and name of file upload is also same as what i am passing controller
public ActionResult Create()
{
return View();
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "Officername,Designation,FileBeforeTour,FileAfterTour,FileBeforeTourName,FileAfterTourName")] FileDetails fileDetails)
{
if (ModelState.IsValid)
{
string uploadedfilename = Path.GetFileName(fileDetails.filebeforetourupload.FileName);
if (!string.IsNullOrEmpty(uploadedfilename))
{
db.FileUpload.Add(fileDetails);
db.SaveChanges();
return RedirectToAction("Index");
}
}
return View(fileDetails);
}
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Web;
namespace OnlineStationaryRegister.Models
{
public class FileDetails
{
[Key]
public int FileId { get; set; }
public string Officername { get; set; }
public string Designation { get; set; }
public string FileBeforeTour { get; set; }
public string FileAfterTour { get; set; }
public string FileBeforeTourName { get; set; }
public string FileAfterTourName { get; set; }
[NotMapped]
public HttpPostedFileBase filebeforetourupload { get; set; }
[NotMapped]
public HttpPostedFileBase fileaftertourupload { get; set; }
}
}
#model OnlineStationaryRegister.Models.FileDetails
#{
ViewBag.Title = "Create";
}
<h2>Create</h2>
#using (Html.BeginForm("Create","File",FormMethod.Post, new { enctype = "multipart/form-data" }))
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>FileDetails</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.Officername, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Officername, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Officername, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Designation, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Designation, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Designation, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.Label("File", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
<input type="file" name="filebeforetourupload" />
</div>
</div>
#*<div class="form-group">
#Html.LabelFor(model => model.FileAfterTour, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
<input type="file" name="fileaftertourupload" />
</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")
}
Change your controllers method as,This will fix your issue
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(FileDetails fileDetails)
{
if (ModelState.IsValid)
{
string uploadedfilename =
Path.GetFileName(fileDetails.filebeforetourupload.FileName);
if (!string.IsNullOrEmpty(uploadedfilename))
{
db.FileUpload.Add(fileDetails);
db.SaveChanges();
return RedirectToAction("Index");
}
}
return View(fileDetails);
}
Okay then this is what you should do. Instead of putting the HttpPostedFileBase field as part of the model, remove it from there and do this
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "Officername,Designation,FileBeforeTour,FileAfterTour,FileBeforeTourName,FileAfterTourName")] FileDetails fileDetails, HttpPostedFileBase myFile)
{
}
then you can manipulate if from there. Sometimes the browser does not properly include files inside the model.
I have this Issue class. Is there
public class Issue
{
public int IssueId { get; set; }
[Required]
public string ReporterName { get; set; }
[Required]
public string Description { get; set; }
public int? IssueTypeId { get; set; }
public virtual IssueType type { get; set; }
}
Then this is the view I have so I can change the value of the IssueTypeId. However when I try to save it in the database with that code in the controller, I am having an error saying that the ReporterName and Description are still required. How can I only update one specific value in database, in this case IssueTypeId?
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Issue</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
#Html.HiddenFor(model => model.IssueId)
<div class="form-group">
#Html.LabelFor(model => model.IssueTypeId, "IssueTypeId", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownList("IssueTypeId", null, htmlAttributes: new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.IssueTypeId, "", new { #class = "text-danger" })
</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>
}
My code in controller
public ActionResult AssignFixer(int issueId, int issueTypeId)
{
var issue = new Issue { IssueId = issueId , IssueTypeId= issueTypeId};
using (var newContext = new SystemContext())
{
newContext.Issues.Attach(issue);
newContext.Entry(issue).Property(i => i.IssueTypeId).IsModified = true;
newContext.SaveChanges();
}
return View(issue);
}
Instead of attaching the issue in newContext.Issues. First get the instance and then update it. Like:
var existingIssue = newContext.Issues.Where(i => i.IssueId == issueId).FirstOrDefault();
existingIssue.IssueTypeId = issueTypeId;
newContext.SaveChanges();
This question already has answers here:
Asp.Net MVC: Why is my view passing NULL models back to my controller?
(2 answers)
Closed 5 years ago.
I'm trying to send a form to ActionResult method but it is null always. In fact, I got the error Value cannot be null. but I don't know why I got it the error.
Here is ActionResult code and my view.
public class VocabularyController : Controller
{
private VocabContext _context;
public VocabularyController()
{
_context = new VocabContext();
}
// GET: Vocabulary
[Route("New")]
public ActionResult New()
{
return View();
}
[HttpPost]
public ActionResult Save(Vocabulary word)
{
if (ModelState.IsValid)
{
_context.Vocabularies.Add(word);
_context.SaveChanges();
}
return RedirectToAction("dashboard", "Home");
}
}
==============================
#model EnglishTest.Models.Vocabulary
#{
ViewBag.Title = "New";
}
<div class="row">
<div class="col-lg-12">
<div class="element-wrapper">
<h6 class="element-header">New Word Form</h6>
<div class="element-box">
#using (Html.BeginForm("Save", "Vocabulary", FormMethod.Post))
{
<div class="form-group">
#Html.LabelFor(m => m.Word)
#Html.TextAreaFor(m => m.Word, new { #class = "form-control", #placeholder = "Word" })
#Html.ValidationMessageFor(m => m.Word)
</div>
<div class="row">
<div class="col-sm-12">
<div class="form-group">
#Html.LabelFor(m => m.Defination)
#Html.TextAreaFor(m => m.Defination, new { #class = "form-control", #placeholder = "Definition" })
#Html.ValidationMessageFor(m => m.Defination)
</div>
</div>
</div>
<div class="row">
<div class="col-sm-12">
<div class="form-group">
#Html.LabelFor(m => m.Synonym)
#Html.TextAreaFor(m => m.Synonym, new { #class = "form-control", #placeholder = "Synonym" })
#Html.ValidationMessageFor(m => m.Synonym)
</div>
</div>
</div>
<div class="row">
<div class="col-sm-12">
<div class="form-group">
#Html.LabelFor(m => m.PersianTranslate)
#Html.TextAreaFor(m => m.PersianTranslate, new { #class = "form-control", #placeholder = "Persian Translation" })
#Html.ValidationMessageFor(m => m.PersianTranslate)
</div>
</div>
</div>
<div class="row">
<div class="col-sm-12">
<div class="form-group">
#Html.LabelFor(m => m.Examples)
#Html.TextAreaFor(m => m.Examples, new { #class = "form-control", #placeholder = "Examples" })
#Html.ValidationMessageFor(m => m.Examples)
</div>
</div>
</div>
#Html.HiddenFor(m => m.Id)
<div class="form-buttons-w"><button class="btn btn-primary" type="submit"> Save</button></div>
}
</div>
</div>
</div>
</div></div>
==============================
public class Vocabulary
{
public int Id { get; set; }
[Required]
public string Word { get; set; }
[Required]
public string Defination { get; set; }
[Required]
public string Synonym { get; set; }
[Required]
public string PersianTranslate { get; set; }
[Required]
public string Examples { get; set; }
}
I Changed the input parameter to my model name, it works fine.
public ActionResult Save(Vocabulary vocabulary)
Specify a post to the form:
#using (Html.BeginForm("Save", "Vocabulary", FormMethod.Post))
Also the second # is not requried:
Html.BeginForm("Save", "Vocabulary", FormMethod.Post)
Visual Studio 2015 Update 1.
MVC 5.2.3.
.NET 4.5.2
It's picking up the Display Name ok, but it's not honoring the Required attribute, it would seem. Thanks!!!
View:
#model Insure.Entities.Policy
#{ ViewBag.Title = "Policy"; }
<h2>Policy</h2>
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Create</h4>
<hr />
#Html.ValidationSummary(true)
<div class="form-group">
#Html.LabelFor(model => model.EffDate, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.EffDate)
#Html.ValidationMessageFor(model => model.EffDate)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.ExpDate, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.ExpDate)
#Html.ValidationMessageFor(model => model.ExpDate)
</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>
Model:
using System;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
namespace Insure.Entities
{
public class Policy
{
public int PolicyID { get; set; }
public Guid PolicyNumber { get; set; }
[Required(ErrorMessage = "Effective Date Required")]
[DataType(DataType.DateTime)]
[DisplayName("Effective Date")]
public DateTime EffDate { get; set; }
[Required(ErrorMessage = "Expiration Date Required")]
[DataType(DataType.DateTime)]
[DisplayName("Expiration Date")]
public DateTime ExpDate { get; set; }
}
}
Controller:
// POST: Policy/Create
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(FormCollection collection)
{
try
{
if (ModelState.IsValid)
{
// TODO: Add logic to insert to DB
return RedirectToAction("Index");
}
else
{
return View();
}
}
catch
{
return View();
}
}
public ActionResult Create(FormCollection collection)
should be
public ActionResult Create(Policy myPolicyModel)
Then validation will be executed on the model.
I have a web application with this controller:
public class ServiceRequestController : Controller
{
[Authorize(Roles = "Customer")]
public ActionResult Create()
{
return View();
}
[Authorize(Roles = "Customer")]
public ActionResult CreateNewUserAccount()
{
return View();
}
[Authorize(Roles = "Customer")]
[HttpPost]
public ActionResult CreateNewUserAccount(ServiceRequest serviceRequest)
{
if (ModelState.IsValid)
{
serviceRequest.Log.Id = User.Identity.GetUserId().ToString();
serviceRequest.Log.DateTimeLogged = System.DateTime.Now;
serviceRequest.LogID = db.Logs.Max(item => item.LogID);
serviceRequest.EstimatedResolveDate serviceRequest.CalculateEstimatedResolveDate();
db.ServiceRequests.Add(serviceRequest);
db.SaveChanges();
return RedirectToAction("AllServiceRequests", "Log");
}
return View(serviceRequest);
}
The serviceRequest.Log.Id = User.Identity.GetUserId().ToString(); (And any preceding line if this is commented out) throws a null reference exception. I presume the serviceRequest is somehow null?
The ActionLink which requests the CreateNewUserAccount() page is:
#Html.ActionLink("New User Account", "CreateNewUserAccount", "ServiceRequest")
I'm not sure how to resolve this exception?
The model is:
public partial class ServiceRequest
{
public int ServiceRequestID { get; set; }
public Nullable<int> LogID { get; set; }
public string RequestType { get; set; }
[DisplayName("Additional Information")]
[Required]
[StringLength(200)]
public string AdditionalInformation { get; set; }
public DateTime EstimatedResolveDate { get; set; }
[Required]
[DisplayName("Delivery Date")]
public DateTime DeliveryDate { get; set; }
public virtual Log Log { get; set; }
public DateTime CalculateEstimatedResolveDate()
{
return System.DateTime.Now.AddDays(3);
}
}
View code:
#model OfficiumWebApp.Models.ServiceRequest
#{
ViewBag.Title = "New User Account";
}
#using(Html.BeginForm("CreateNewUserAccount", "ServiceRequest", FormMethod.Post))
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
#Html.ValidationSummary(true)
<div class="form-group">
#Html.LabelFor(model => model.RequestType, new { #class = "control-label col-md-2" })
<div class="col-md-3">
<div class="editor-field">
#Html.TextBoxFor(model => model.RequestType, new { #Value = ViewBag.Title, #readonly = "readonly" })
#Html.ValidationMessageFor(model => model.RequestType)
</div>
</div>
</div>
<div class="form-group">
#Html.Label("Name of Account Holder", new { #class = "control-label col-md-2" })
<div class="col-md-3">
<div class="editor-field">
#Html.TextBox("AccountName")
#Html.ValidationMessageFor(model => model.RequestType)
</div>
</div>
</div>
<div class="form-group">
#Html.Label("Department", new { #class = "control-label col-md-2" })
<div class="col-md-3">
<div class="editor-field">
#Html.TextBox("Department")
#Html.ValidationMessageFor(model => model.RequestType)
</div>
</div>
</div>
<div class="form-group">
#Html.Label("Location", new { #class = "control-label col-md-2" })
<div class="col-md-3">
<div class="editor-field">
#Html.TextBox("Location", null, new { id = "Location" }))
#Html.ValidationMessageFor(model => model.RequestType)
</div>
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.AdditionalInformation, new { #class = "control-label col-md-2" })
<div class="tags">
<div class="col-md-10">
#Html.TextAreaFor(model => model.AdditionalInformation)
#Html.ValidationMessageFor(model => model.AdditionalInformation)
</div>
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.DeliveryDate, new { #id = "VisitDateLabel", #class = "control-label col-md-2" })
<div class="col-md-3">
<div class="editor-field">
#Html.JQueryUI().DatepickerFor(model => model.DeliveryDate).Inline(false)
#Html.ValidationMessageFor(model => model.DeliveryDate)
</div>
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<button type="submit" class="btn btn-default"><span class="glyphicon glyphicon-floppy-save"></span></button>
</div>
</div>
</div>
}
You need to return the view i.e.
[Authorize(Roles = "Customer")]
public ActionResult CreateNewUserAccount()
{
var model = new ServiceRequest();
model.Log = new Log();
return View(model);
}
In your view you need to add a model reference too at the top i.e.
#model ServiceRequest
You could also initialise the Log object in your model as follows:
public class ServiceRequest
{
public ServiceRequest()
{
Log = new Log();
}
....
}
An action link will not post your model back, you need to include it within a form and include all the model values that you want to be updated on the client i.e.
#using (Html.BeginForm("CreateNewUserAccount", "ServiceRequest", FormMethod.Post)){
#Html.EditorFor(m => m.AdditionalInformation)
...
<input type="submit" value="submit" />
Update
Taken from the below comments, this was resolved by creating a new log on post i.e.
var log = new Log {
Id = User.Identity.GetUserId().ToString(),
DateTimeLogged = System.DateTime.Now,
LogID = db.Logs.Max(item => item.LogID) };
serviceRequest.Log = log;