Persist values between multiple Posts - asp.net

Hello I am not able to retain values on multiple posts and “Post1” action function in my in my controller always has MyViewModelObj.Field2 as null .I expect it to retain the old value in the 2nd post
How to I make the MyViewModel model class object persist the values ?
Mymodels.cs ( Model)
namespace RetainTest.Models
{
public class MyViewModel
{
public string Field1 { get; set; }
public string Field2 { get; set; }
public string Field3 { get; set; }
public string Field4 { get; set; }
}
}
RetainView.cshtml ( View )
#model RetainTest.Models.MyViewModel
#{
ViewBag.Title = "RetainView";
}
<h2>RetainView</h2>
#using (Html.BeginForm("Post1", "Retain", FormMethod.Post,
new { enctype = "multipart/form-data" }))
{
#Html.AntiForgeryToken()
#Html.HiddenFor(model => model.Field1);
#Html.HiddenFor(model => model.Field2);
#Html.HiddenFor(model => model.Field3);
#Html.HiddenFor(model => model.Field4);
<div class="form-horizontal">
<h4>MyViewModel</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.Field1, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Field1, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Field1, "", new { #class = "text-danger" })
</div>
</div>
#{
if ( Model.Field2 == "Val2")
{
<div class="form-group">
#Html.LabelFor(model => model.Field2, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Field2, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Field2, "", new { #class = "text-danger" })
</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")
}
RetainController.cs ( Controller )
namespace RetainTest.Models
{
public class RetainController : Controller
{
// GET: Retain
public ActionResult Index()
{
MyViewModel MyViewModelObj = new MyViewModel();
MyViewModelObj.Field1 = "Val1";
return View("RetainView", MyViewModelObj);
}
[HttpPost]
public ActionResult Post1(MyViewModel MyViewModelObj)
{
if (string.IsNullOrEmpty(MyViewModelObj.Field2 ))
{
MyViewModelObj.Field2 = "Val2";
}
return View("RetainView", MyViewModelObj);
}
}
}

Try this:
namespace RetainTest.Models
{
public class MyViewModel
{
[Required(ErrorMessage = "Field1 is required")]
public string Field1 { get; set; }
[Required(ErrorMessage = "Field2 is required")]
public string Field2 { get; set; }
public string Field3 { get; set; }
public string Field4 { get; set; }
}
}
#model RetainTest.Models.MyViewModel
#{
ViewBag.Title = "RetainView";
}
<h2>RetainView</h2>
#using (Html.BeginForm("Post1", "Retain", FormMethod.Post, new { id = "form", enctype = "multipart/form-data"}))
{
#Html.AntiForgeryToken()
#Html.HiddenFor(model => model.Field1);
#Html.HiddenFor(model => model.Field2);
#Html.HiddenFor(model => model.Field3);
#Html.HiddenFor(model => model.Field4);
<div class="form-horizontal">
<h4>MyViewModel</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
<Label for="Field1" class="control-label col-md-2">Field1 </label>
<div class="col-md-10">
#if(Model.Field1 == "Val1")
{
<input type="text" name="Field1" id="Field1" class="form-control" value="#Model.Field1">
}
else
{
<input type="text" name="Field1" id="Field1" class="form-control">
}
<span class="field-validation-valid text-danger"
data-valmsg-for="Field1"
data-valmsg-replace="true">
</span>
</div>
</div>
<div class="form-group">
<Label for="Field2" class="control-label col-md-2">Field2 </label>
<div class="col-md-10">
#if(Model.Field2 == "Val2")
{
<input type="text" name="Field2" id="Field2" class="form-control" value="#Model.Field2">
}
else
{
<input type="text" name="Field2" id="Field2" class="form-control">
}
<span class="field-validation-valid text-danger"
data-valmsg-for="Field2"
data-valmsg-replace="true">
</span>
</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")
}
namespace RetainTest.Models
{
public class RetainController : Controller
{
private MyViewModel MyViewModelObj = new MyViewModel();
// GET
public ActionResult Index()
{
if (Session["MyObj"] != null)
MyViewModelObj = (MyViewModel)Session["MyObj"];
else
MyViewModelObj.Field1 = "Val1";
return View("RetainView", this);
}
[AcceptVerbs(HttpVerbs.Post)]
[ValidateInput(false)]
public ActionResult Post1(FormCollection form)
{
MyViewModelObj.Field1 = form.Get("Field1");
MyViewModelObj.Field2 = form.Get("Field2");
if (string.IsNullOrEmpty(MyViewModelObj.Field2))
MyViewModelObj.Field2 = "Val2";
// here you need to store the data somewhere!
// session, database.
// just an example:
Session.Add("MyObj", MyViewModelObj);
return View("RetainView", this);
}
}
}
I used the session to retain the values of the object but there are a few other ways to store the data. The above code will post the user input to the controller and retain he values in the session.

Got answer from Stephen Muecke
"Your view has a hidden input for each property of your model. The DefaultModelBinder reads the first name/value pair for each property in the request and ignores all others. Since the hidden inputs are first, the values of your EditorFor() methods are ignored. You only ever bind the initial vales of your model, not the edited values (making your form rather pointless). Remove the hidden inputs!"

Related

Asp.net MVC - input type="file" validation error

i create a form that have 2 input text and 1 input file, when i selected the image and click on submit button an error occurs for the input file
i don't have any validation on input file!
this is my view code:
#model Test.Models.Domain.tblCategory
#{
Layout = null;
}
#using (Html.BeginForm("AddOrEditeCat", "Admin", FormMethod.Post, new {enctype="multipart/form-data",onsubmit="return SubmitCatForm(this)" }))
{
#Html.AntiForgeryToken()
#Html.HiddenFor(model => model.id)
#Html.HiddenFor(model => model.Pic)
<div class="form-group">
#Html.Label("Title", new { #class = "control-label" })
#Html.EditorFor(model => model.Title, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Title)
</div>
<div class="form-group">
#Html.Label("Text", new { #class = "control-label" })
#Html.EditorFor(model => model.Text, new { htmlAttributes = new { #class = "form-control" } })
</div>
<div class="form-group">
#Html.LabelFor(model=>model.Pic, new { #class = "control-label" })
<img src="#Url.Content(Model.Pic)" style="margin:10px" height="150" width="150" id="imagePreview" />
<input type="file" id="ImageUpload" name="ImageUpload" accept="image/jpeg,image/png" onchange="ShowImagePreview(this,document.getElementById('imagePreview'))" />
</div>
<div class="form-group">
<input type="submit" value="Submit" class="btn btn-primary" />
<input type="reset" value="Reset" class="btn btn-primary btn-danger" />
</div>
}
and this is my model:
public partial class tblCategory
{
public int id { get; set; }
[Required(ErrorMessage = "*")]
public string Title { get; set; }
public string Text { get; set; }
[DisplayName("Image")]
public string Pic { get; set; }
public HttpPostedFileBase ImageUpload { get; set; }
public tblCategory()
{
Pic = "~/Cntent/upload/img/cat/defalt.png";
}
}

Asp.net Cant Post Value to Controller

I want to post email and password to Another Controller's action (to Create )
But values are not posted. When i look at the User1Controller's its writing values are Null like in the screenshot. Please help I'm stuck with this hours and cant understand
ScreenShot
My User1.cs
public partial class Users1
{
public string userEmail { get; set; }
public string userPassword { get; set; }
}
My User1Controller
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "userEmail,userPassword")] Users1 baska)
{
if (ModelState.IsValid)
{
db.Users1.Add(baska);
db.SaveChanges();
return RedirectToAction("Index","Home");
}
return RedirectToAction("Login", "Home");
}
My Login.cshtml file
#using (Html.BeginForm("Create","Users1",FormMethod.Post))
{
#Html.AntiForgeryToken()
<div class="custom-login-panel">
<div class="container">
<div class="row">
<div class="col-md-offset-3 col-md-6">
<img class="profile-img" src="~/images/userlogo.svg"
alt="">
<div class="form-login">
<h4 style="color:white;">Giriş ve Kayıt Ekranı</h4>
<div class="form-group">
#Html.EditorFor(m => m.user1.userEmail, new { htmlAttributes = new { #class = "form-control" ,placeholder="Email" } })
#*#Html.ValidationMessageFor(model => model.user1.userEmail, "", new { #class = "text-danger" })*#
</div>
<div class="form-group">
#Html.EditorFor(m => m.user1.userPassword, new { htmlAttributes = new { #class = "form-control", placeholder = "Passwordd" } })
#*#Html.ValidationMessageFor(model => model.user1.userPassword, "", new { #class = "text-danger" })*#
</div>
<div class="wrapper">
<div class="form-group">
<span class="group-btn">
<input style="width:40%;" type="submit" value="Giriş" class="submit btn btn-primary">
<input style="width:40%;" type="submit" value="Kayıt Ol" class="submit btn btn-primary">
</span>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
}
On your Login.cshtml:
you should declare your model.
On your httpget action:
you should declare a new instance of your Users1 class and pass it like a parameter to your return() method.
On your httppost action:
You should receive the model as parameter.
I guess that with these changes, it would work.

Why all fields are required when using ASP.NET EF6 auto created controller and view

I am new to ASP.NET EF6 and need some help here, I created a datamodel and a datacontext
public class RepositoryDbContext : DbContext
{
public RepositoryDbContext()
: base("DefaultConnection")
{
}
public DbSet<Repository> Repositories { get; set; }
}
public class Repository
{
public int ID { get; set; }
public string SKU { get; set; }
public string Title { get; set; }
}
and the html page
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Order</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.SKU, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.SKU, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.SKU, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Title, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Title, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Title, "", new { #class = "text-danger" })
</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")
}
Then I used Visual Studio 2015 to auto create the controller and views, but in the create page, the sku and title are both required, how could I get rid of the required validation for Title field.
Thanks very much, I tried googling it but no luck.

Adding CheckBoxList of items to MVC 4 View

I have the challenge of adding CheckBoxList of items to MVC 4 view. I have several models in the same the MVC 4 view. So I created the View Model below
public class ArticlesVM
{
public article articles { get; set; }
public game games { get; set; }
public gallery mgallery { get; set; }
public team teams { get; set; }
public ArticlesVM()
{
Teams = new List<TeamVM>();
}
public List<TeamVM> Teams { get; set; }
}
to include 4 models as it properties. I then created a view where each of the properties can be used independently as follows:
#model TeamBuildingCompetition.ViewModels.ArticlesVM
#{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_Layout_new.cshtml";
}
<h2>Index</h2>
#using (Html.BeginForm("Create", "TBCArticles", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4></h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.articles.featuredImage, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-8">
#Html.TextBoxFor(model => model.articles.featuredImage, new { #type = "file" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.games.gameName, "Select a Game", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-8">
#Html.DropDownList("gameID", (IEnumerable<SelectListItem>)ViewBag.gameList, "Select Game", new { #class = "form-control" })
</div>
</div>
<div class="form-group">
#Html.HiddenFor(model => model.teams.teamID)
#Html.HiddenFor(model => model.teams.teamName)
#Html.DisplayFor(model => model.teams.teamName)
<div class="col-md-8">
#for(int i = 0; i < Model.Teams.Count; i++){
#Html.HiddenFor(model => model.Teams[i].ID)
#Html.CheckBoxFor(model => model.Teams[i].IsSelected)
#Html.LabelFor(model => model.Teams[i].IsSelected, Model.Teams[i].TeamName)
}
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.articles.articleTitle, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-8">
#Html.EditorFor(model => model.articles.articleTitle, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.articles.articleTitle, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.articles.articleContent, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-8">
#Html.EditorFor(model => model.articles.articleContent, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.articles.articleContent, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.mgallery.picturePath, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-8">
#Html.TextBoxFor(model => model.mgallery.picturePath, new { #type = "file", #multiple = "true" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-8">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
Here is my TeamVM model below:
public class TeamVM
{
public int ID { get; set; }
[Required(ErrorMessage = "Please Enter Your Team Name")]
[Display(Name = "Team Name")]
public string TeamName { get; set; }
[DisplayName("Team Picture")]
[ValidateFile]
public HttpPostedFileBase TeamPicture { get; set; }
[Required]
[Display(Name = "Description")]
public string Description { get; set; }
[Required(ErrorMessage = "Please Enter Team Content")]
[Display(Name = "Content")]
[MaxLength(500)]
public string Content { get; set; }
public bool IsSelected { get; set; }
}
Added the following to my controller action:
[HttpGet]
public ActionResult Index(ArticlesVM model)
{
model = new ArticlesVM ();
model = new ArticlesVM();
var teamList = (from p in db.teams
select new TeamVM()
{
ID = p.teamID,
TeamName = p.teamName,
IsSelected = p.IsSelected
});
model.Teams = teamList.ToList();
ViewBag.gameList = new SelectList(db.games, "gameID", "gameName");
return View(model);
}
And now have a null reference error in this portion of the view:
<div class="form-group">
#Html.HiddenFor(model => model.teams.teamID)
#Html.DisplayFor(model => model.teams.teamName)
<div class="col-md-8">
#for(int i = 0; i < Model.Teams.Count; i++){
#Html.HiddenFor(model => model.Teams[i].ID)
#Html.CheckBoxFor(model => model.Teams[i].IsSelected)
#Html.LabelFor(model => model.Teams[i].IsSelected, Model.Teams[i].TeamName)
}
</div>
</div>

File Upload in ASP.NET MVC 5

I am unable to upload file in folder. I am not able to find the mistake. The UploadFile View returns on same view after uploading file.
Model Class:
public class Upload
{
public int UploadId { get; set; }
public string UploadTitle { get; set; }
public string UploadURL { get; set; }
}
Here is the Controller(FileUpload) Action:
public ActionResult UploadFile(HttpPostedFileBase file, Upload upload)
{
if (ModelState.IsValid)
{
if (file != null)
{
string fil = System.IO.Path.GetFileName(file.FileName);
string path = System.IO.Path.Combine(Server.MapPath("/Content/Uploads/Files"), fil);
file.SaveAs(path);
upload.UploadURL = "/Content/Uploads/Files/" + file.FileName;
}
db.Uploads.Add(upload);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(upload);
}
In my View:
#using (Html.BeginForm("UploadFile, "FileUpload", FormMethod.Post, new { enctype = "multipart/Form-data" }))
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
<div class="control-label col-md-2">
<label for="file">Upload Image for Slide:</label>
</div>
<div class="col-md-10">
<input type="file" name="file" id="file" style="width:50%" />
</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>
}
Hi I have tried your same code its works for me.
Controller
[HttpPost]
public ActionResult UploadFile(HttpPostedFileBase file)
{
if (ModelState.IsValid)
{
if (file != null)
{
string fil = System.IO.Path.GetFileName(file.FileName);
string path = System.IO.Path.Combine(Server.MapPath("/Content/Uploads/Files"), fil);
file.SaveAs(path);
}
return RedirectToAction("Index");
}
return View("UploadFile");
}
View
#using (Html.BeginForm("UploadFile", "Home", FormMethod.Post, new { enctype = "multipart/Form-data" }))
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
<div class="control-label col-md-2">
<label for="file">Upload Image for Slide:</label>
</div>
<div class="col-md-10">
<input type="file" name="file" id="file" style="width:50%" />
</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>
}
I have found small mistake in you code in Html.BeginForm in action name " (double quotes is missing)
I forgot to mention the required field on UploadURL in above model class:
public class Upload
{
public int UploadId { get; set; }
public string UploadTitle { get; set; }
[Required]
public string UploadURL { get; set; }
}
Required Field validation on UploadURL field restricted the file upload here. I removed the Required field validation from the field.

Resources