I am trying very hard to rewrite this question better than my previous effort which received no responses. Even though I’m nearly done with this application, I am still a relative newbie at programming and it seems like one challenge just leads to another. I have looked at many posts related to the problem of passing a parameter to several Partial Views in a single view page. So let’s take this in order from the AlertPick.cshtml page where the user chooses one of three Alert_Identifier/SelectedAlertIndex parameters from the application database. I’m only showing the #model and Select Tag Form.
#model edxl_cap_v1_2.Models.ContentViewModels.EdxlCapMessageViewModel
#{
<h4>#Model.Alerts.Count Alerts</h4>
<form asp-controller="Alerts" asp-action="PickAlert" method="post">
<select class="cap_select" id="cap_select" style="width:100%;max-width:95%;"
asp-for="SelectedAlertIndex" asp-items="Model.Alert_Identifiers">
<option>Select one</option>
</select>
<br />
<input type="submit" name="PickAlert" value="Pick Alert to Assemble EDXL-Cap Message" />
</form>
}
This takes the user to thePickAlert.cshtml page, a table of five rows where the first four rows are the Data Categories of the application: Alert, Info, Area and Resource each with the Alert_Identifier repeated as a reminder in a text box followed by its own submit button named Check Alert, Check Info, Check Area, and Check Resource, respectively. These submit buttons take the user to a _DetailsAlert.cshtml, _DetailsInfo.cshtml, _DetailsArea.cshtml, and _DetailsResource.cshtml pages and they work correctly, with the data item names and values from the record that matches the Alert_Identifier. The fifth row repeats the Identifier and its button reads Add All, to assemble the whole set together for review and takes the user to the_Assemble.cshtml page below, where the individual data categories are correctly assembled with the data item names, but lack the correct data values that match the record that corresponds to the Alert_Identifier. I’m thinking that I need to add a third parameter for the SelectedAlertIndex or Alert_Identifier to each of the #Html.Partial(...) Views, but I haven’t found the correct form/syntax for that, and If someone could supply that or point me to an example similar enough to this, I would deeply appreciate it.
#model edxl_cap_v1_2.Models.ContentViewModels.EdxlCapMessageViewModel
<!DOCTYPE html>
<head>
<meta name="viewport" content="width=device-width" />
<link rel="stylesheet" href="~/css/capv1_2_refimp.css" />
<title>Assembled EDXL-CAP Message</title>
</head>
<h4>Assemble EDXL-CAP Message</h4>
<!-- DetailsAlert -->
<div class="content-wrapper">
#Html.Partial("_DetailsAlert", Model.Alert)
</div>
<!-- End of DetailsAlert -->
<!-- DetailsInfo -->
<div class="content-wrapper">
#Html.Partial("_DetailsInfo", Model.Info)
</div>
<!-- End of DetailsInfo -->
<!-- DetailsArea -->
<div class="content-wrapper">
#Html.Partial("_DetailsArea", Model.Area)
</div>
<!-- End of DetailsArea -->
<!-- DetailsResource -->
<div class="content-wrapper">
#Html.Partial("_DetailsResource", Model.Resource)
</div>
<!-- End of DetailsResource -->
Responding to first comment below, I'm showing the InfosController.cs code for _DetailsInfo(int? id) the controller action for the Info Data Category. It is virtually identical for each of the data categories except that the line ... .SingleOrDefaultAsync(m => m.InfoIndex == id); becomes ....SingleOrDefaultAsync(m => m.AlertIndex == id); and the method itself becomes_DetailsAlert(int? id).
// GET: Infos/Details/5
public async Task<IActionResult> _DetailsInfo(int? id)
{
if (id == null)
{
return NotFound();
}
var info = await _context.Info
//.Include(e => e.Elements)
// .ThenInclude(d => d.DataCategory)
.AsNoTracking()
.SingleOrDefaultAsync(m => m.InfoIndex == id);
if (info == null)
{
return NotFound();
}
return View(info);
}
PickAlert method from AlertsController follows:
public IActionResult PickAlert(Alert obj, int? SelectedAlertIndex)
{
if (SelectedAlertIndex.HasValue)
{
ViewBag.Message = "Alert loaded successfully";
}
return View(_context.Alert.Where(x => x.AlertIndex == SelectedAlertIndex));
}
I am not sure if I got the requirement correctly, but I think you have to create another model for all 4 partial views, e.g. for Alert, create a new model
class AlertModel:EdxlCapMessageViewModel
{
int SelectedAlertIndex {get;set;}
}
And then your view would look like:
<!-- DetailsAlert -->
<div class="content-wrapper">
#Html.Partial("_DetailsAlert",new AlertModel { Alert = Model.Alert,
SelectedAlertIndex = <ID SOMEHOW>
});
</div>
In .net core when I need to pass around a lot of data across the views, I usually find it cleanest to use services and DI. First, you can create a class that could store a set of data:
class MyDataForViews {
// the following is an example. You can have any properties
public string Info { get; set; }
}
You now have to add this class as a service. To do so go to your startup class and add the following within the services function:
services.AddScoped<MyDataForViews>();
Scoped means that the framework will create a new object of MyDataForViews for each HTTP request. No matter how many places you "inject" an object of MyDataForViews, it would use the same object across the current HTTP request. You can also replace the function with AddSingleton if you want to use the same object throughout the web app. The following is how you inject an object into your controller:
public class MyController : Controller
{
MyDataForViews myData;
// in controllers injection is done using the constructor
public MyController(MyDataForViews MyData) => myData = MyData;
public IActionResult Index()
{
myData = .... // assign all required data here
View();
}
}
Once this is done, instead of passing models to each view, you can inject the data into views using the following:
#inject MyDataForViews MyData;
Once you use this line on the top of any view, you can use the MyData object and there is no need to pass models to each partial view.
Here's a bit more detailed answer, since you've said at softwareengineering.stackexchange.com site that you still need help with this.
Let's first make sure you understand the basics correctly.
When it comes to passing data to the view, each controller in ASP.NET MVC has a property named ViewData, which is essentially a dictionary of key-value pairs. The ViewData itself has a property called Model, and this is what you access in the page using the Razor syntax #Model. You can use this property to pass a model that is strongly-typed, to avoid using magic strings for the keys of ViewData.
Note: ViewBag is a dynamic wrapper around the ViewData, so it's essentially the same thing (ViewBag.SomeProperty is the same as ViewData['SomeProperty']); the use of ViewBag is discouraged, though.
In a controller action when you do something like return View(), ASP.NET uses the cshtml page as a template to create actual HTML, and return it as the response to the client (this is all server-side).
There are a few ways to pass data to the view which are equivalent, for example:
ViewData.Model = someObject;
return View();
is the same as:
return View(someObject); // the View method can accept a model object
When it comes to partial views, by default, they get passed a copy of the parent page ViewData (this includes the reference to the Model), so you don't have to do anything special to pass this data to a partial view (but you can pass data of your choice if you want to).
The select tag helper renders (generates HTML) for the select element with the options specified. This is then sent as HTML to the client. On the client side, when the user clicks the submit button, a POST request is sent to the server, which is ultimately handled by the method PickAlert method on the AlertsController. If everything is setup correctly, you should get the SelectedAlertIndex as the parameter. Note that this is happening back at the server side, and that you now need to again return a page as the response.
You can pick the corresponding Alert object from your _context. Use the FirstOrDefault method for this instead of Where, as you only need a single item (convert types for comparison if necessary - e.g., if you have a string, but you are comparing to an int, or something along those lines).
var selectedAlert = _context.Alert.FirstOrDefault(x => x.AlertIndex == SelectedAlertIndex);
Now, all you need to do is set this selectedAlert and any other data that you need as a property on your model object (or under some key in ViewData), and render the correct view.
Note that if you just return View(model) without specifying the name of the view, the system will look for a view with the same name as your action method (here, PickAlert.cshtml), so use return View("ViewName", model) to change that if necessary.
For example, based on the code you've posted in your question, you could do something like this:
[HttpPost]
public IActionResult PickAlert(int? SelectedAlertIndex)
{
var model = new EdxlCapMessageViewModel(/* ... params, if any */);
if (SelectedAlertIndex.HasValue)
{
ViewBag.Message = "Alert loaded successfully";
var selectedAlert = _context.Alert.FirstOrDefault(x => x.AlertIndex == SelectedAlertIndex);
// I added a property to your model to store the alert;
// if you already have one, just use that one instead.
model.SelectedAlert = selectedAlert;
}
return View("YourViewName", model);
}
The YourViewName should be the parent view that has the partial views in it (the "Assembled EDXL-CAP Message" view, I presume).
BTW, I know that the way the system is passing the parameters to the action methods in a controller may seem a bit like magic, but it's convention-based. In the example above, it works because the parameter is named SelectedAlertIndex, and the model object has a property with the same name (and because you've specified that property in the select tag helper using asp-for="SelectedAlertIndex"). You can also modify the method signature so that it receives the entire model object (assuming that the model class is not too complicated - you can read more about how parameter binding works here):
[HttpPost]
public IActionResult PickAlert(EdxlCapMessageViewModel model)
{
// extract the index from model.SelectedAlertIndex
// you can also pass this same model object to the view
// (set some properties first if necessary)
// ...
}
Now for the partial views. Assuming that you are relying on the default mechanism which passes the parent ViewData to each partial view, you need to modify each partial view so that the code is written under the assumption that you can access the selected alert using #Model.SelectedAlert (the property you've set in the PickAlert action).
For example, a here's a simple partial view:
<div style="border: solid 1px #000000; padding: 30px; margin: 2px 2px 10px 2px;">
<p>The selected index is: #Model.SelectedAlert.AlertIndex</p>
</div>
Note that I'm just using the same model as in the parent view to access the SelectedAlert object: #Model.SelectedAlert.AlertIndex.
Again, when rendering the partial views, if you pass no additional parameters, they'll get a copy of the ViewData dictionary, and the same Model:
#Html.Partial("_DetailsAlert");
If you pass something else as the model, e.g., only the selected alert, then you need to change the partial view code accordingly:
#Html.Partial("_DetailsAlert", Model.SelectedAlert);
<div style="border: solid 1px #000000; padding: 30px; margin: 2px 2px 10px 2px;">
<p>The selected index is: #Model.AlertIndex</p>
</div>
Note that now, in the partial view, the local #Model refers to what was #Model.SelectedAlert in the parent view. (In other words, here #Model is of type Alert.) This only affects the ViewData.Model property; the key-value pairs stored in ViewData are still the same as those in the parent view.
Related
first post. Trying so solve an issue I am seeing here between my Razor view and model. I have a popup window that is being fed a partial view and model.
public IActionResult ClickedCovid19Question(int id)
{
var existingQ = db.CustomerInfoItems.Find(id);
var suffix = existingQ.Suffix;
if (suffix.Length == 2)
suffix = suffix.Insert(0, "0");
var salesman = SalesmanHelper.GetSalesmanNum();
var par = db.Pars.Where(p => p.AccountNo == existingQ.CustNum).Where(p => p.Suffix == suffix)
.Where(p => p.SalesmanNumber == salesman).FirstOrDefault();
var clickedCovid19Model = new ClickedCovidQuestionModel
{ //insert model data here }
clickedCovid19Model.Machines = db.MachinePopulationItems
.Where(m => m.CustNum == existingQ.CustNum)
.ToList();
return View("~/Views/Covid19/_ClickedCovid19Question.cshtml", clickedCovid19Model);
}
This works great on the first page render. I see the data fill my UI elements that are called from the #model on the razor page. When my user updates a field here and submits, I use this function
function SaveClickedCovid19Question(idJS) {
C19ParChanged('#Model.Par');
var jsonJS = SerializeForm("#c19QuestionForm");
$.ajax({
url: '/Covid19/SaveClickedCovid19Question',
type: 'GET',
data:
{
id: idJS,
json: jsonJS
},
success: function (data) {
Alert(data);
RefreshLV("CovidQuestions");
HideWindow("#Covid19Question");
},
error: function (data, error, e2) {
debugger;
}
});
}
However, after the popup window is closed, and another popup is opened, we call that same ClickedCovid19Question IActionResult to populate our form again. It populates the UI fine with the new model it generated, debugging shows it creates a new model with all the correct data.
The issue arrises when a user submits this form again, the model on the Razor view seems to think it is still the model of the very first submission. An example of this is the first line of the javascript function. When the razor view was created, it had the correct #Model.Par data, as I could see when I created a few elements to display it. However, when trying to capture that data using #Model.Par, it captures the original Model.Par data.
Long story short, subsequent popups don't overwrite the Model data from the very first one. I am stumped, because this system works in so many other areas of our codebase.
I can fix this buy creating hidden elements that will store the data I need to send in any requests, but I feel like there has to be a better answer than that.
Edit: Below is an example I was using to test. The view part below will always display the correct par data in the id=parID input box. However, on the second popup and everytime after, if I was to run the simple javascript function below to find the data held by model, it will ALWAYS update to the data from the first model the page ever rendered, which seems inconsistent with other areas of my code that do work normally.
function updateParID() {
$("#c19QuestionForm").find("#parID").val('#Model.Par');
}
<input id="parID" type="text" disabled="disabled" value="#Model.Par"/>
<partial name="Forms/_FormDropDown" model=#(new FormDropDownModel { Name = "Par", Values = Lists.ParStates(), Value = Model.CallsPerYear}) />
<button type="submit" onclick="RefreshWindow('#Model.ID')">Refresh</button>
<button type="submit" onclick="updateParID()">Update Par ID</button>
That #Model.Par (or whatever prop you have in #Model) renders before anything shows up in browser.
Razor page will render your view and then pass it to browser.
so if you want to fetch data using ajax you should manually put data received from ajax into you html controls.
Have a nice coding day :)
So, I actually ended up solving this. My issue was, trying to bind the data from the #Model.Par or any model data INSIDE a javascript function will ALWAYS bind using the initial model. Every subsequent call to this function will ALWAYS only use that very first model.
My solution that I overlooked was to actually send the data to the function from the model as a parameter first, and not try to bind it inside the javascript function.
Example: My edit has these lines
function updateParID() {
$("#c19QuestionForm").find("#parID").val('#Model.Par');
}
<button type="submit" onclick="updateParID()">Update Par ID</button>
When I change the order of how I capture that model to this:
function updateParID(parID) {
$("#c19QuestionForm").find("#parID").val(parID);
}
<button type="submit" onclick="updateParID('#Model.Par')">Update Par ID</button>
This now correctly captures the model data that is present. I am sure there is some reason javascript works this way, but it is unknown to me, if anyone can shed light on it. Forgive me if it is a simple answer, I am new to web programming. Thank you all for helping out!
I am at a loss on how to do this. I've tried every search I can think of. Any help/direction would be greatly appreciated.
The customer wanted to be able to load a partial view dynamically from a wysiwyg editor. So, I made a method in the controller that searches for a special tag that gets the name of the partial view. Got that to work fine. Now the customer wants to load and post data to/from the partial view.
I was able to get it loaded by doing this - finalhtml += PartialView("~/Views/Global/Partials/" + commandContents + ".cshtml").RenderPartialViewToString();
If I name the controller the exact name of the partial view plus controller ie: SamplePartialController, I can get the view post back to the controller, BUT I can't figure out how to load an initial index method on the partial no matter what I try.
It would be nice if I could define the initial index method and controller name programmatically, just not seeing a way.
I am fairly new to mvc, been doing asp.net for over a decade, and this may be very obvious, but I'm just not finding a way. Thanks!
Not sure I understand clearly the issue. I also had a lot of troubles working with partial views (to post data, to load them back if something wrong happened in the post action...).
It seems like you want to fill your partial view if some parameters are here when loading the index.
In the Controller.Index (or where you get your parameters) you can assign some ViewModel values, or use the ViewBag/ViewData.
In the index view, you can call where you need the RenderPartialAsync() based on your parameters setted previously
this.ViewData["error"] = Model.Error;
this.ViewData["partialGuid"] = Guid.NewGuid();
this.ViewData["foo"] = bar;
await Html.RenderPartialAsync("_PartialViewName", Model.PartialViewModel, this.ViewData);
And use your partial view the same way you do from an ajax call.
If you need to post data from your partial view, I struggled a lot with some things:
A FormContext is required in the partial view
#if (this.ViewContext.FormContext == null)
{
this.ViewContext.FormContext = new FormContext();
}
If you allow to push multiple times your partial view and post them, making a custom collectionId helps a lot when in the controller post action
#{
var collectionId = $"PartialItems[{this.ViewData["partialGuid"]}].{{0}}";
}
// then later...
<input class="form-control"
data-val="true"
data-val-required="#(string.Format(ApplicationResources.Error_Required, ApplicationResources.FieldFirstName))"
id="#(string.Format(collectionId, "FirstName"))"
name="#(string.Format(collectionId, "FirstName"))"
type="text"
value="#(string.IsNullOrWhiteSpace(Model.FirstName) ? string.Empty : Model.FirstName)" />
<span class="field-validation-valid text-danger"
data-valmsg-for="#(string.Format(collectionId, "FirstName"))"
data-valmsg-replace="true"></span>
// And in your Index ViewModel, something like that to get the collection in the controller post action
public IDictionary<string, PartialViewModel> PartialItems { get; set; }
If you call the new partial view with Ajax, after the first render of the view, reset the jquery validator if needed
$.ajax({
// ...
success: function (res) {
// do your stuff
$('#parentId').prepend(res);
// reinit the validation
$("form").each(function () { $.data($(this)[0], 'validator', false); });
$.validator.unobtrusive.parse("form");
}
});
It is almost everything I can think of that bugged me when dealing the first time with all this partial view things. Hope something here can help you.
I'm trying to load my partial view with some data from database, but I'm getting following issue when I run the application:
Child actions are not allowed to perform redirect actions.
I don't know why this is happening because I'm pretty new with MVC technology.
Here is my PartialViewResult method in a controller:
public PartialViewResult UnReadEmails()
{
if (User.Id != null)
{
List<Emails> resultList = EmailController.GetUnreadEmailsByUserId(User.Id);
return PartialView("~/Views/Emails/_UnReadEmails.cshtml", resultList);
}
return PartialView("Error, not found!");
}
And here is my partialview itself, it is called _UnReadEmails (as you can see I'm displaying here info about sender and email body), PartialView is retrieving list of Emails that I'm sending to from my Controller
#model IEnumerable<Emails>
foreach (var item in Model)
{
<li>
<a>
<span>
<span>#item.EmailSender</span>
<span class="email">
#item.Body;
</span>
</a>
</li>
}
After I tried to load my partial view on this way:
#Html.Action("UnreadEmails", "Message")
I started to receive following issue that I mentioned in my Title,
I already tried few things to solve this like changing #Html.Action("UnreadEmails", "Message") to #Url.Action("UnreadEmails", "Message") etc etc but that didn't solve my issue.
EDIT: It allways breaks on this line (on view) :
#Html.Action("UnreadEmails", "Message")
It never goes into code behind..
After Chris suggestion on another post I added [AllowAnonymous] on the top of the method:
[AllowAnonymous]
public PartialViewResult UnReadEmails()
{
if (User.Id != null)
{
List<Emails> resultList = EmailController.GetUnreadEmailsByUserId(User.Id);
return PartialView("~/Views/Emails/_UnReadEmails.cshtml", resultList);
}
return PartialView("Error, not found!");
}
EDIT EDIT EDIT:
Interesting fact is that whatever I wrote in my Controller's method and even if I comment all code, it will still break on a View, that means it will never came into a Controller's method. I put breakpoing there at the begining of the UnReadEmails method and it was never hitted, it allways breaks on a View!
EDIT AFTER MAURIZIO suggestion to change it to #Html.RenderPartial
Than I received following issue:
The partial view 'UnReadEmails' was not found or no view engine
supports the searched locations. The following locations were
searched: ~/Views/Dashboard/UnReadEmails.aspx
~/Views/Dashboard/UnReadEmails.ascx ~/Views/Shared/UnReadEmails.aspx
~/Views/Shared/UnReadEmails.ascx ~/Views/Dashboard/UnReadEmails.cshtml
~/Views/Dashboard/UnReadEmails.vbhtml
~/Views/Shared/UnReadEmails.cshtml ~/Views/Shared/UnReadEmails.vbhtml
EDIT:
Compiler Error Message: CS0120: An object reference is required for the non-static field, method, or property 'MessageController.UnReadEmails()'
I tried to make UnReadEmails() as static but than I received following error :
Error 1 An object reference is required for the non-static field,
method, or property 'System.Web.Mvc.Controller.PartialView(string,
object)' ...Controllers\Message\MessageController.cs
Since your partial view is not in the Shared folder you need to provide the full path
{#Html.RenderPartial("~/Views/Emails/_UnReadEmails.cshtml")}
Since that view needs the list of emails you need to add that as parameter
{#Html.RenderPartial("~/Views/Emails/_UnReadEmails.cshtml",EmailController.GetUnreadEmailsByUserId(User.Id))}
The best aproach would be to create a property in the Model (List<Emails> lstUnreadEmails) and load that list of emails in a method of the MessageController, so that the information is ready for the partial to be render with this instruction:
{#Html.RenderPartial("~/Views/Emails/_UnReadEmails.cshtml",Model.lstUnreadEmails)}
In case you dont have a "main model" you could store that in a ViewBag, calling this from a MessageController method
ViewBag.lstUnreadEmails = EmailController.GetUnreadEmailsByUserId(User.Id);
And in the View use this
{#Html.RenderPartial("~/Views/Emails/_UnReadEmails.cshtml",ViewBag.lstUnreadEmails)}
I have a multi-language website and views content (including the markup) can differ from language to language. That's why I cannot just localize strings and put them into resources.
For example, my view in Russian:
<div class="card">
<div class="card-image">
<img src="~/Images/CardHeaders/Business_CreditsSME.jpg" />
</div>
<div class="card-content">
Text
</div>
</div>
View in English:
<p>Text</p>
I see two ways to localize this:
Create Page.cshtml and Page.en.cshtml, and create a custom LocaleView() method in controller which will use the localized view files.
The problem is that Views do not always differ. It means that sometimes I will duplicate the markup.
Copy all the HTML markup in my resources as it is, and use Html.Raw(Resources.PageView).
It is not convenient to create, modify or read HTML which is located in a resource flies
Moreover, I do not like Html.Raw method at all and prefer not to use it anywhere
How do you localize large views of different structures?
I have combined two solutions.
I have overriden View method in my base controller so that it looks for the existent localized view. Now, if my views differ too much, I simply create View.en.cshtml file and it is automatically being processed by a controller:
public abstract class BaseController : Controller
{
protected override ViewResult View(string viewName, string masterName, object model)
{
if (string.IsNullOrEmpty(viewName))
viewName = (string)RouteData.Values["action"];
string localizedViewName = $"{viewName}.{CultureInfo.CurrentCulture.Name}";
bool hasLocalizedView = ViewEngines.Engines
.FindPartialView(ControllerContext, localizedViewName)
.View != null;
return base.View(hasLocalizedView ? localizedViewName : viewName, masterName, model);
}
}
If my views have the same structure, then I don't create separate files, but simply use the same view with localized strings within it like this:
<div class="card">
<div class="card-image">
<img src="~/Images/CardHeaders/Business_CreditsSME.jpg" />
</div>
<div class="card-content">
#GlobalResources.LocalizedText
</div>
</div>
The structure now looks like:
- Views
-- About
--- History.cshtml
--- History.kk.cshtml
--- History.en.cshtml
--- Vacancies.cshtml
where Vacancies.cshtml file uses resources to localize a page, and History* files are localized like a plain text without resources.
Awesome question!
Between these two option the first one look a little bit better.
But one thing that I usually do. It's created an HTML helper to locate the localised view.
So, you will be able to use it on the view like this:
#Html.RenderLocale("YourView", ...);
Then, in your RenderLocale, you change the file path to the view that the user wants.
public static string RenderLocale(this HtmlHelper helper, string target, ...)
{
var filePath = this.getLocaleFilePath(target); //it returns yourView.cshtml or yourView.ru.cshtml
return this.Action(filePath); // it renders or performs the action you want
}
I have the following setup in my solution, described in an earlier post:
How to implement Sitecore Template inheritance with Glass Mapper
I'm able to display the content of inherited fields now. However when I try to edit them in the page editor the EditFrame is not rendered, nothing gets rendered actually. Not sure what I'm still missing. Here's my controller and view:
Controller:
public class NavigationController : Controller
{
// GET: /Navigation/
public ActionResult Index()
{
var context = new SitecoreContext();
var page = context.GetCurrentItem<HomePage>();
return View("/Views/Navigation.cshtml", page);
}
}
View:
#inherits Glass.Mapper.Sc.Web.Mvc.GlassView<Sitecore.Training7.Internet.Core.Models.HomePage>
#if (Model != null)
{
<h3 class="text-muted">Field: #Editable(x => x.NavigationTitle)</h3>
}
When I hit the preview button the value is displayed, I don't see the value in the PageEditor though. What am I still missing here? Any ideas?
This is just a guess based on the HomePage model that you included in your other post, but I think you need to add an ID property to your model. See http://glass.lu/docs/tutorial/sitecore/tutorial05/tutorial05.html
I see your other post now, please add the Id:
[SitecoreId]
Guid Id{ get; }
In page editor mode, sitecore would require the mapped Id to know which item the value belongs to. So you will need to add this to your model too.
If by any chance you are using TDS or something similar - you'll see that the property is added by default in the base class for all model classes by default.