ASP.NET MVC-5 sever side validation not working - c#

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

File Upload Control Get Returned Null

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.

How to save one specific value in database

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();

why ActionResult method parameter is null in asp.net MVC? [duplicate]

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)

ModelState.IsValid always true

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.

NullReferenceException ASP.NET MVC 5

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;

Categories