Why is my ASP.NET MVC Edit Form not retaining data? - asp.net-mvc

On my edit view, the information doesn't seem to be displayed on the form in the textboxes. Any idea why this is happening? Any help would be greatly appreciated.
Here's how my edit functions inside the controller look like:
[HttpGet]
[Authorize(Roles = "Admin")]
public ActionResult Edit(int id)
{
var logic = new ContactBUS();
var user = logic.GetContact(id);
var mUser = Membership.GetUser(user.Username);
bool memUserExists = doesUserExist(mUser);
if (memUserExists)
{
var model = new RoleListViewModel
{
AllRoles = Roles.GetAllRoles().ToList()
};
return View(model);
}
return View(logic.GetContact(id));
}
[HttpPost]
[Authorize(Roles = "Admin")]
public ActionResult Edit(Contact contact)
{
var logic = new ContactBUS();
if (ModelState.IsValid)
{
logic.EditContact(contact);
return RedirectToAction("List");
}
else
return View(contact);
}
}
Edit.cshtml:
#model ContactWeb.Models.RoleListViewModel
<h2>Edit</h2>
<div style="float:left;width:350px;">
#{Html.RenderPartial("Form", new ContactWebLibrary.Contact());}
</div>
and Form.cshtml:
#model ContactWebLibrary.Contact
#using (Html.BeginForm()) {
<input type="hidden" value="#Model.Id" />
<fieldset id="ContactEditor">
<legend>Fields</legend>
<div>
#Html.LabelFor(c=>c.FirstName, "First Name")
#Html.TextBoxFor(c=>c.FirstName)
#Html.ValidationMessageFor(c=>c.FirstName)
</div>
<div>
#Html.LabelFor(c=>c.LastName, "Last Name")
#Html.TextBoxFor(c=>c.LastName)
#Html.ValidationMessageFor(c=>c.LastName)
</div>
...
<input type="submit" value="#(Model.Id == 0 ? "Create" : "Edit" )" />
</fieldset>
}

If memUserExists is true then a new RolesListViewModel is passed to the Edit view. This in turn passes a brand new Contact model to the partial view each time this partial view is rendered:
#{Html.RenderPartial("Form", new ContactWebLibrary.Contact());}
So the contact used in the partial will not contain any information to display, hence, no values are being displayed.
Does logic.GetContact(id) return a RoleListViewModel? Otherwise, when memUserExists is false, I don't think the following line would work when returning the Edit view:
return View(logic.GetContact(id));
And also, the following line in your [HttpPost]:
return View(contact);
This passes a Contact object to a view that is expecting a RoleListViewModel.
Hope this helps.

Related

Why my MVC view passes null but not the value it has? [duplicate]

This question already has an answer here:
Html.DisplayFor not posting values to controller in ASP.NET MVC 3
(1 answer)
Closed 5 years ago.
View shows proper value (OrderId = 3):
// GET:
public ActionResult ConfirmOrder()
{
//simplified code here
var model = new ConfirmOrderViewModel()
{
OrderId = 3,
};
return View(model);
}
View works fine one way (value visible on the screen) Html-part below:
#model Test.Models.Views.ConfirmOrderViewModel
#{
ViewBag.Title = "My title";
}
<h2>#ViewBag.Title</h2>
#using (Html.BeginForm("ConfirmOrder", "Client", FormMethod.Post, new {
#class = "form-horizontal", role = "form" }))
{
#Html.AntiForgeryToken()
<div class="row" style="padding:10px; margin:15px">
<div>
<div class="col-sm-3">
#Html.DisplayFor(m => m.OrderId)
</div>
</div>
</div>
}
ConfirmOrderViewModel class looks like this:
public class ConfirmOrderViewModel
{
public int OrderId { get; set; }
}
4. But when it comes to post it back, only null I'm having:
// POST:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult ConfirmOrder(ConfirmOrderViewModel ViewModel)
{
//at this moment: ViewModel.OrderId = null
return RedirectToAction("Index");
}
Controller Name is ok, Methods works... no errors. Just null after clicking the OK button on page. What can cause bad model binding here?
The DisplayFor helper method will just render the value of the OrderId property. As the name suggests, It is more for displaying to the user. If you want the value for OrderId to be posted to the http post action method, you need to keep that in in a form field inside the form.
You can keep in a hidden field inside the form
#using (Html.BeginForm("ConfirmOrder", "Client"))
{
#Html.DisplayFor(m => m.OrderId)
#Html.HiddenFor(a=>a.OrderId)
<input type="submit" value="Confirm" />
}

Two strongly types partial views in one razor view

I am using Asp.Net identity logic module for authentication process. I am using this theme for login and signup and external logins all in one view.
Here is my Login.cshtml view that contain social login, register and login partials
#using Helping.ViewModels
#{
ViewBag.Title = "Log in";
}
<div class="container">
<div class="row">
<br />
<br />
<div class="col-lg-4">
<div>
<section id="socialLoginForm">
#Html.Partial("_ExternalLoginsListPartial", new ExternalLoginListViewModel { Action = "ExternalLogin", ReturnUrl = ViewBag.ReturnUrl })
</section>
</div>
</div>
<div class="col-lg-4">
<h2><b>Sign Up</b></h2>
<hr />
#Html.Partial("Register")
</div>
<div class="col-lg-4">
<h2><b>Log In</b></h2>
<hr />
#Html.Partial("LocalLogin")
</div>
</div>
</div>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
LocalLogin and Register are the strongly typed partial views.Problem is that when I try to Login with a user that doesnot exist it returns the model , here is the action
public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
{
if (ModelState.IsValid)
{
var user = await UserManager.FindAsync(model.UserName, model.Password);
if (user != null)
{
if (!await UserManager.IsEmailConfirmedAsync(user.Id))
{
string callbackUrl = await SendEmailConfirmationTokenAsync(user.Id, "Confirm your account-Resend");
ViewBag.errorMessage = "You must have a confirmed email to log on.";
return View("Error");
}
else
{
await SignInAsync(user, model.RememberMe);
return RedirectToLocal(returnUrl);
}
}
else
{
ModelState.AddModelError("", "Invalid username or password.");
}
}
// If we got this far, something failed, redisplay form
return View(model);
}
It return following error
The model item passed into the dictionary is of type 'Helping.ViewModels.LoginViewModel', but this dictionary requires a model item of type 'Helping.ViewModels.RegisterViewModel'.
My Register view expects RegisterViewModel and My LocalLogin expects LoginViewModel
#using Helping.ViewModels
#model LoginViewModel
#model HelpingHands.ViewModels.RegisterViewModel
How to provide both the models with one view need help ?
You need to combine both your LoginViewModel and RegisterViewModel into one model (ViewModel).
Like..
public class LoginRegisterModel
{
public LoginViewModel LoginModel {get;set;}
public RegisterViewModel RegisterModel {get;set;}
}
Then you can pass this viewModel to your view..
#model Helping.ViewModels.LoginRegisterModel
Which says this view will be using the class LoginRegisterModel as the model..
And inside the view for your two partial views you can use..
Html.Partial("LocalLogin", Model.LoginModel)
Html.Partial("Register", Model.RegisterModel)
The error your getting is because you are not passing any model to your Register view and by default the model passed to your main view is carried forward to the call of partial Register view.
** I m on mobile, forgive me for bad formatting. And if anyone can format the code section its greatly appreciated**

How to check each form controller's type posted to action method?

View:
#using (Html.BeginForm())
{
#Html.Label("WebLinkLabel")
#Html.Editor("WebLinkTextbox")
#Html.Label("WebEnabledLabel")
#Html.CheckBox("WebEnabledCheckbox")
<input name="Save" type="submit" value="Save" />
}
Action Method:
[HttpPost]
public ActionResult Index(FormCollection collection)
{
foreach (var key in collection.AllKeys)
{
var typee = collection.GetType();
}
return View();
}
GetType() gives me that:
collection.AllKeys.GetType()
{Name = "String[]" FullName = "System.String[]"} System.Type {System.RuntimeType}
I would like to know like the first controller is of type Textbox, another one is Checkbox etc..

how to pass data from view to controller

I am new to asp.net MVC5 and i am trying to pass data from view to controller as a string.
Here is controller class:
namespace Movies.Controllers
{
public class HelloWorldController : Controller
{
// GET: HelloWorld
public ActionResult Index()
{
return View();
}
[HttpPost]
public ActionResult welcome(FormCollection fc, string reportName)
{
ViewBag.Message = reportName;
return View();
}
}
}
Here is Index View:
#{
ViewBag.Title = "MVC Movies";
}
<h2>My Movies List</h2>
<p>Hellow from our view template</p>
#using (Html.BeginForm("Welcome", "HelloWorld", FormMethod.Get))
{
<p>
<input type="text" name="reportName" />
<input type="submit" />
</p>
}
Here is welcome view:
#{
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>welcome</h2>
#{
ViewBag.Title = "Welcome";
}
<ul>
#for (int i = 0; i < 2; i++)
{
<li>#ViewBag.Message</li>
}
</ul>
Actually my Index method is passing a view that will have a textbox for string in it in a form and then on clicking submit button application should pass that string in the Welcome method in the same controller. On clicking submit button browser is showing a windows that resources con't be found.
Whats the problem..? thank you for your time..:)
1) The action name is case sensitive, you are using "Welcome" in the form definition , but the action must has the name "welcome" with w lower case.
2) Your form is doing a GET but you are specting a POST in the action
[HttpGet]
public ActionResult welcome(FormCollection fc, string reportName)
{
ViewBag.Message = reportName;
return View();
}
Replace FormMethod.Get with FormMethod.Post in your beginform.
Modify FormMethod.Get to FormMethod.Post:
#using (Html.BeginForm("Welcome", "HelloWorld", FormMethod.Post))
{
<p>
<input type="text" name="reportName" />
<input type="submit" />
</p>
}
Change your action implementation to this:
[HttpPost]
public ActionResult welcome(FormCollection fc)
{
ViewBag.Message = fc["reportName"];
return View();
}
However, I'd strongly suggest that you create a view model for your form and use it instead of FormCollection.

Model value lost on postback

I have the following models:
class A
{
// ...some properties
public B InnerField { get; set; }
}
and
class B
{
public int Id { get; set; }
// ..other properties
}
and a page that has a model Class A and inside the page I have a partial view bound to Class B inside a form.
The value of the Id (in the partial view) is set correctly to the model's Id value (different from 0) but when I submit the page the model has the Id value 0. The Id value is not modified in the component or elsewhere.
Page
...other parts of main page
<%using (Html.BeginForm("ModifyHotel", "Hotel",
FormMethod.Post, new { enctype = "multipart/form-data"}))
{%>
<% Html.RenderPartial("~/Views/Shared/ModifyBaseItem.ascx",
new ModifyItemRequestBaseView() { ItemId = Model.Item.Id });%>
<%}%>
...other parts of main page
Partial View
...other parts of partial view
<br/>
Add Photo: <%:Html.FileBoxFor(x => x.PhotoFile, null)%>
<br/>
Add Video: <%:Html.FileBoxFor(x => x.VideoFile, null)%>
<br/>
<input type="submit" value="Submit changes" />
...other parts of partial view
What can I do to keep the value of the inner model when the post is made?
Thanks,
Controller:
public class HomeController : Controller
{
public ActionResult Index()
{
A model = new A() { InnerField = new B() { Id = 5 }};
return View(model);
}
[HttpPost]
public ActionResult Index(B model)
{
//on postback the model should have the value 5 here
return View();
}
}
View:
#model MvcApplication11.Models.A
#using (Html.BeginForm())
{
#Html.Partial("_IndexForm", Model.InnerField)
<input type="submit" />
}
Partial:
#model MvcApplication11.Models.B
#Html.EditorFor(m => m.Id)

Resources