Form Values from Model Not Updating in View After Post - c#

I believe I'm missing something quite trivial here, but I'm not spotting it. I have a Post method, which modifies a Model property. I then want that model property to reflect the new property value. So here are the pieces:
Controller:
[HttpPost]
public ActionResult Index(HomeModel model)
{
ModelState.Clear(); //Didn't help
model.MyValue = "Hello this is a different value";
return View(model);
}
Model:
public class HomeModel
{
[Display(Name = "My Message")]
public string MyValue { get; set; }
}
View:
#model MyApp.Models.HomeModel
#{
ViewBag.Title = "My MVC App";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title></title>
</head>
<body>
<div>
#using (Html.BeginForm("Index", "Home"))
{
<h5>Hello</h5>
<input id="SendMessage" type="submit" value="Send Message"/>
#Html.LabelFor(m => m.MyValue)
}
</div>
</body>
</html>
When I debug the controller I can see the updated model, but my LabelFor always has the Display attribute as opposed to the value I provided of "Hello this is a different value". What am I missing here that this label is not updated?

#Html.LabelFor displays your property name (or the name defined in your DisplayAttribute), whereas #Html.DisplayFor displays your property content. If your want "Hello this is a different value" displays, replace #Html.LabelFor by #Html.DisplayFor

The html helper look at the ModelState when binding their values and then in the model.
So if you intend to modify any of the POSTed values inside your controller action make sure you remove them from the model state first:
ModelState.Remove("PropertyName");
Read this MVC 3 - Html.EditorFor seems to cache old values after $.ajax call

That's the purpose of LabelFor, display the property name. Either use EditorFor or just access the model property directly inside a label tag it to your view
<h5>Hello</h5>
<input id="SendMessage" type="submit" value="Send Message"/>
<label>#Model.MyValue</label>

Related

Reusing the same html code as a partial view 'n' number of times in the same index.cshtml page

I have a partial view which renders a visual form made entirely in HTML with some .css. What I want to do is reuse this same form in the same page [n] number of times. In my HomeController class I am instantiating the model as such:
public IActionResult Index()
{
List<Foo> foos = new List<Foo>();
foos.Add(new Foo { Name = "John" });
foos.Add(new Foo { Name = "Dave" });
foos.Add(new Foo { Name = "Sean" });
foos.Add(new Foo { Name = "Alan" });
return View(foos);
}
Then in my index.cshtml I am iterating using the list I receive from my controller and generating a partial view based on the length of my list
#model List<HelloWorld.Models.Foo>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Foo</title>
<link rel="stylesheet" href="~/foo/styles.css" />
<script src="https://code.jquery.com/jquery-3.3.1.js"></script>
<script src="~/foo/FooActions.js"></script>
</head>
<body>
#{
foreach (Foo foo in Model)
{
ViewData["Name"] = foo.Name;
<partial name="_Foo" view-data="ViewData" />
}
}
</body>
</html>
This is how I have my partial view set up:
<script type="text/javascript">
init('#ViewBag.Name');
</script>
<div class="foo-background">
<section>
<div>
<span class="score-text" id="redText">0</span>
</div>
<div class="green-bar"></div>
<div class="red-bar"></div>
<div>
<span class="bonus-score-text" id="greenText">0</span>
</div>
</section>
<section>
<div class="alphanumeric-display">
<p class="alphanumeric-display-text" id="textLine1">Text</p>
<p class="alphanumeric-display-text" id="textLine2">Text</p>
<p class="alphanumeric-display-text" id="textLine3">Text</p>
</div>
<div>
<span class="person-grade-text" id="goldText">0</span>
</div>
</section>
</div>
This form pulls data from a local database and displays data based on the person its tied to. The data shows up fine if its only displaying data of one person in the page. I'm using JavaScript to grab either the class or the id of these html elements and update their respective data.
But now what its doing is showing all the forms side-by-side, only, the data is wrong. None of the forms show the data from the table as they appear in the database. Upon closer inspection looks like it has a problem where each of these forms cant have the same class or ids. I'm getting this in error in all places where I have class or id elements
id attribute value must be unique: Document has multiple static
elements with the same id attribute: textLine1
Its the same error for each of my html elements.
Can someone help me understand what I am doing wrong? What can I do in order to get this to work properly?

partial view form submits object bound to parent view model instead of its own model

I have the following bits from my test application.
A method used for posting the data from a partial view.
public IActionResult AddPayor(Payor newPayor)
{
if (ModelState.IsValid)
{
mvSrv.SaveOnePayor(newPayor);
return RedirectToAction("Index", "Payor");
}
else
{
return View();
}
}
And index cshtml view where I want to have a list of item plus the ability to add more.
Notice the model class PayorView; it contains a list of payors to use in the ViewPayor view and a single payor to use in the AddPayor view. I do it this way so that the AddPayor can have an object passed down even when the list is empty. Earlier I tried to have only the list as the model but sending the [0] element failed when list was empty.
#addTagHelper "*, Microsoft.AspNetCore.Mvc.TagHelpers"
#model FSA_Tracker.ViewModels.PayorView
#{
Layout = "_Layout";
}
<partial name="ViewPayor" for="payors" />
<partial name="AddPayor" for="payor" />
The partial view for AddPayor is just an input form. The model object is pass down from the parent view.
#addTagHelper "*, Microsoft.AspNetCore.Mvc.TagHelpers"
#model FSA_Tracker.Models.Payor
<fieldset>
<form asp-action="AddPayor" method="post">
<div asp-validation-summary="ModelOnly" class="input-validation-error"></div>
<div id="formContainer">
<p>
<label asp-for="Name"></label>
<input asp-for="Name" />
<span asp-validation-for="Name"></span>
</p>
<p>
<button type="submit">Add Payor</button>
</p>
</div>
</form>
</fieldset>
My problem is that the newPayor argument in my post method does not get initialized, but rather what gets initialized is the PayorView.payor property in the parent view model object. So I can make it work if I change to
and I extract the payor from there.
Is there a way to prevent my partial view from binding its object to the parent view model? Preferably from the parent view.
Thanks
try passing in the payor model into your partial view like:
<partial name="ViewPayor" model="#Model.Payor" />
Got it. I needed to instantiate and pass the new new model into the partial. Now I see what Matthias L meant. I just didn't know I could go to a different namespace than the one in the declaration section. This will give the partial view a new Provider object rather than an attribute from the parent view.
#{
var provider = new FSA_Tracker.Models.Provider();
<partial name="AddProvider" model="#provider" />
}

Cant find page after POST redirect C#

I go to a View, submit data via POST, but the redirect cannot find the Controller method. What am I doing wrong here? After submitting the form I get:
404 error: cannot find page. URL is: http://localhost:52008/InternalController/UpdateCardFormPost
Snippet from InternalController.cs:
public ActionResult UpdateCardFormView()
{
var CardToUpdate = new CardView();
return View(CardToUpdate);//return implementation of Cards.cshtml with the empty model that was passed to it
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult UpdateCardFormPost(CardView c)
{
CardModelIO.WriteCard(c);//#TODO: IMPLEMENT
return View("CardDetailView", c);
}
UpdateCardFormView.cshtml (the view with the form I am submitting):
#using LeanKit.API.Client.Library.TransferObjects
#model CardView
<!DOCTYPE html>
<html>
<!--Form used to change a card
STARTING DISPLAY called by in Internal/UpdateCardFormView
ENDING DISPLAY (post) called by UpdateCardForm in InternalController a specified below-->
<head>
</head>
<body>
#Html.BeginForm("UpdateCardFormPost", "InternalController", FormMethod.Post)
#Html.TextBoxFor(c => c.AssignedUserName);
<input type="submit" value="Submit Changes" />
</body>
</html>
Heres the CardDetailView.cshtml (the view I should be redirected to):
#using LeanKit.API.Client.Library.TransferObjects
#model IEnumerable<CardView>
<!--used for displaying an individual card in detail view
referenced in UpdateCardFormPost() method of Internal controller-->
<!DOCTYPE html>
<html>
<head>
</head>
<body>
CardView j = Model;
<p>j.AssignedUserId</p>
</body>
</html>
You've specified the controller name as InternalController but it's probably just called "Internal".
Try changing
#Html.BeginForm("UpdateCardFormPost", "InternalController", FormMethod.Post)
to
#Html.BeginForm("UpdateCardFormPost", "Internal", FormMethod.Post)
you are missing closing form tag
you should do it like
using (#Html.BeginForm("UpdateCardFormPost", "InternalController", FormMethod.Post))
{
...
}
#using(Html.BeginForm())
{
#Html.TextBoxFor(c => c.AssignedUserName);
<input type="submit" value="Submit Changes" />
}

Two Partial Views in One Page?

I tried to use 2 partial views under 1 view/page - first half page for search filters & 2nd half page for table display. Its working also,but the issue is the white color content panel is in fixed size. i.e., if my table got data it comes out of the white color panel.
<section class="content admin_table">
#RenderBody()
</section>
I use above class in Layout. In Index View, I render both Partial views. My code part is below
#Html.Partial("_view1", Model.Filter)
#Html.Partial("_view2", Model.Result)
My IndexPage
#model SW.Web.ViewModels.CommonVM
#{
Layout = "~/Views/Shared/_Layout1.cshtml";
ViewBag.Title = "Title";
ViewBag.Header = "Details";
}
<link href="~/Content2/plugins/datatables/dataTables.bootstrap.css" rel="stylesheet" />
<!DOCTYPE html>
#section JavaScript{
<Script> .....</script>
<Script> .....</script>
}
#Html.Partial("_view1", Model.Filter)
#Html.Partial("_view2", Model.Result)
and My Partial view 1
#model SW.Web.ViewModels.viewmodel1
#{
using (Html.BeginForm("Index", "Details", FormMethod.Post, new { d= Model }))
{
#Html.ValidationSummary(true)
<div>.....Design</div>
}
and my partial view 2
#model IEnumerable<SW.Web.ViewModels.Viewmodel2>
#{
<div> Designs for partial view 2</div>
}
I understand this is over a year old but just in case someone stumbles across this post.
RenderPartialView is written like the following:
#{#Html.RenderPartial("_yourPartial", yourModel)}
So create One view with
Search partial view like
//Serach view
<div class="white">
<h2>Search view</h2>
<--! search coading-->
#Html.RenderPartial("Table_View", objectvalue2);
</div>
Use below line
#Html.RenderPartial("_SearchView", objectvalue1);
in another page
by controller action
#Html.Action("action1", "Controller", new { id = Model.idOfPart1 })
#Html.Action("action2", "Controller", new { id = Model.idOfPart2 })
by rendering view
# Html.Render ("ParialView1", Model.model1)
# Html.Render ("PartialView2", Model.model2)

Modify existing object in ASP.NET

I have some problem with my ASP.NET MVC application. How can I modify an existing object created previously in different ActionResult?
I created object in this action:
public ActionResult getLogin(AccountViewModel accountViewModel)
{
Account account2 = de.Accounts.FirstOrDefault(a => a.Username == accountViewModel.Account.Username);
PasswordReminder.PasswordReminder reminder = new PasswordReminder.PasswordReminder();
reminder.showQuestion(account2.Username);
return View("Question", reminder);
}
And I want to add an attribute to the existing reminder object by this ActionResult
#model PasswordReminder.PasswordReminder
#{
Layout = null;
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Question</title>
</head>
<body>
<div>
#Model.questionReminder
#using (Html.BeginForm("Answer", "Account", FormMethod.Post))
{
#Html.TextBoxFor(a => a.reminderAnswer)
<input type="submit" value="Send" />
}
</div>
</body>
</html>
So in my View "Answer" in attribute "reminderAnswer" I entered value but questionReminder is null, so this must be a new object.. Thanks for all help
If I have understood your question correctly, in order to achieve what you are after, the PasswordReminder object that you are using as your Model, must be persisted in the getLogin action, and then passed back separately as the model from your action that feeds your Answer view (but I recommend to use a ViewModel as an abstraction over the previous PasswordReminder object for security)
This would insure you are referencing the previously instantiated PasswordReminder object in your Answer view, in order to modify the value of reminderAnswer property.

Categories

Resources