I'm trying to use a resource file to hold label text for the Model in an MVC 2 project.
I've got the following class...
public class Person
{
[Display(ResourceType = typeof(Resources.Labels),Name="First")]
public string FirstName { get; set; }
public string LastName { get; set; }
}
...and have tried using...
<%: Html.EditorForModel() %>
<%: Html.EditorFor(m => m) %>
<%: Html.LabelFor(m => m.FirstName) %>
...but I'm getting "FirstName" for the label in all instances. Resource file is called Labels.resx, has an entry for "First" and is in Properties folder.
Having read a few posts, I believe this should work in .NET 4 (I'm using VS2010 RTM and have targetted .NET 4).
Should this work?
Thanks in advance
http://weblogs.asp.net/rajbk/archive/2010/04/27/localization-in-asp-net-mvc-2-using-modelmetadata.aspx
must be like below ;
[Required(ErrorMessageResourceType = typeof(Resources), ErrorMessageResourceName = "Required")]
Related
I am new to MVC and am still struggling a bit with what I think is pretty basic mvc stuff. My intended purpose is simply to render textboxes that represent a collection of data objects such that I can validate them easily using DataAnnoations. I've read and understand this tutorial, and have gotten it to work just fine - but it's only validating a single person object one at a time, composed of primitives:
http://weblogs.asp.net/scottgu/archive/2010/01/15/asp-net-mvc-2-model-validation.aspx
My problem is similar to this post, but I was unsuccessful in applying it to my situation with no Razor:
MVC 3 client-side validation on collection with data annotations -- not working
Validation works great on "primitives" like String and int, but I don't understand validation on collections.
Here is the class that represents one instance of my object and some validation:
public class vc_EBTOCRecord
{
[StringLength(10, ErrorMessage = "must be under 10 chars")]
[Required(ErrorMessage = "Problem!")]
public String ItemText;
}
Here is the model that the view inherits:
public class EBTOCViewModel
{
public List<vc_EBTOCRecord> VcEbtocRecordList { get; set; }
}
Here is my controller:
public ActionResult Create()
{
EBTOCViewModel ebtocViewModel = new EBTOCViewModel();
List<vc_EBTOCRecord> vcEbtocRecordList = new List<vc_EBTOCRecord>();
vc_EBTOCRecord vcEbtocRecord = new vc_EBTOCRecord();
vcEbtocRecord.ItemText = "bob";
vcEbtocRecordList.Add(vcEbtocRecord);
vc_EBTOCRecord vcEbtocRecord2 = new vc_EBTOCRecord();
vcEbtocRecord.ItemText = "fred";
vcEbtocRecordList.Add(vcEbtocRecord2);
vc_EBTOCRecord vcEbtocRecord3 = new vc_EBTOCRecord();
vcEbtocRecord.ItemText = "joe";
vcEbtocRecordList.Add(vcEbtocRecord3);
ebtocViewModel.VcEbtocRecordList = vcEbtocRecordList;
return View(ebtocViewModel);
}
and lastly, here is what I am attempting in my view:
<%# Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<vcAdminTool.ViewModels.EBTOCViewModel>" %>
<h2>Create</h2>
<% using (Html.BeginForm()) {%>
<%: Html.ValidationSummary(true) %>
<fieldset>
<legend>Fields</legend>
<% foreach(var thing in Model.VcEbtocRecordList)
{
Html.TextBoxFor(model => thing.ItemText);
//Html.TextBox("hello", thing.ItemText ); didn't work...
//Html.TextBox("hello"); nope, still didn't work
Response.Write("a record is here");
}
%>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
<% } %>
<div>
<%: Html.ActionLink("Back to List", "Index") %>
</div>
When the view renders, "a record is here" is printed three times, indicating to me that MVC recognizes the underlying object I have created, but why won't it render three textboxes?
The desired result is to have three blank validated textboxes. I will then write code that writes the information back to the database if the form is valid.
If you please, what obvious thing am i missing?
In the ever increasingly epic failure that are my Create and Edit forms, I'm still having problems generating checkboxes via Html.Checkbox(). I'm not sure if I should just manually write the HTML at this point.
I have a view model:
public class AdminGameReviewViewModel
{
public Game GameData { get; set; }
public List<Genre> AllGenres { get; set; }
public List<PlatformListing> AllPlatforms { get; set; }
}
And a helper model:
public class PlatformListing
{
public Platform Platform { get; set; }
public bool IsSelected { get; set; }
}
And, I'm trying to generate the checkboxes like so:
<%: Html.Label("Platforms") %><br />
<% Model.AllPlatforms.ForEach(p => Html.Encode(Html.CheckBox("PlatformIDs", p.IsSelected, new { value = p.Platform.PlatformID }))); %>
But, they're not displaying at all.
I'm curious as to why I need to supply a boolean for the checkboxes themselves. I'd think it would simply send back checked values, as an array or list similar to PHP's $_POST. So, I'm not sure if I'm implementing my boolean property correctly, in addition to whatever other brain dead errors I'm committing. The boolean is forcing me to bury the data I want to display/bind further than I'd like, and it's giving me problems 'seeing' what I'm doing wrong.
I keep getting the feeling I'm looking too deeply at my problem, and trying to make the solution more complicated than it should be. Given my inexperience with MVC2/C#, I'm just not sure where to go from here. It doesn't help that this seems to be the one part of form handling that's either glossed over or completely ignored by most demos and tutorials.
So, again, any help would be greatly appreciated.
The problem is you're not writing anything to the Response stream.
Html.Checkbox() returns a string, it doesn't write directly to the response object (nor does Html.Encode() - that just escapes reserved characters and returns the result string). On top of all that, the ForEach extension method only executes an action, it doesn't return a value.
So you have to ditch the ForEach extension, and use the <%= %> or <%: %> code nuggets:
<% foreach (var p in Model.AllPlatforms) { %>
<%= Html.CheckBox("PlatformIDs", p.IsSelected, new { value = p.Platform.PlatformID }) %>
<% } %>
With ASP.NET MVC 1.0, we could write something like:
<label for = "FirstName">First Name:</label>
Which displays "First Name:" on screen. Now, with ASP.NET MVC 2.0, we have
<% = Html.LabelFor(model => model>FirstName)%>
Which displays "FirstName" on the screen. It looks to me a little odd to display things like FirstName, LastName, ... (instead of First Name:, Last Name:, ...). Is there anyway, to get a more explicit text with Html.LabelFor()???
Thanks for helping
You can use this in your model:
[DisplayName("First Name")]
public string FirstName { get; set; }
and you'll need this:
using System.ComponentModel;
You can use this one as well
#Html.Label("Your Custom Label Text in Here")
I have this classes:
public class GroupMetadata
{
[HiddenInput(DisplayValue = false)]
public int Id { get; set; }
[Required]
public string Name { get; set; }
}
[MetadataType(typeof(GrupoMetadata))]
public partial class Group
{
public virtual int Id { get; set; }
public virtual string Name { get; set; }
}
And this action:
[HttpPost]
public ActionResult Edit(Group group)
{
if (ModelState.IsValid)
{
// Logic to save
return RedirectToAction("Index");
}
return View(group);
}
That's my view:
<%# Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<Group>" %>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<% using (Html.BeginForm()) {%>
<fieldset>
<%= Html.EditorForModel() %>
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
<% } %>
<div>
<%=Html.ActionLink("Back", "Index") %>
</div>
</asp:Content>
But ModelState is always invalid! As I can see, for MVC validation 0 is invalid, but for me is valid.
How can I fix it since, I didn't put any kind of validation in Id property?
UPDATE:
I don't know how or why, but renaming Id, in my case to PK, solves this problem.
Do you know if this an issue in my logic/configuration or is an bug or expected behavior?
Just before if (ModelState.IsValid) remove Id index using this line ModelState.Remove("Id") this way when MVC team remove this bug, you just need to remove this line code of your projects.
You have a required field, Id. It's required because it's non-nullable. You must either (1) submit it with your form or (2) change your model to make Id nullable or (3) use a different type.
I can confirm that removing the id index using ModelState.Remove("Id") works.
Could anyone give an elaborate explanation for this alleged "bug"?
Maybe someone from the Microsoft MVC Team could give an explanation?
There are no bugs like this when using the ADO.NET Entity Data Model as a data source - only on Linq To SQL.
Your problem is that you are using a property named 'id' in your model. Try using a different name and you will see it works. Mvc seems to have a problem with that.
I experienced the exact same issue.
One other reason can be:
If you declare your key as some type other than a number e.g String, then since by default it can't auto generate the keys for you, you'll face this error.
I'm having difficulty getting data from a textbox into a Controller. I've read about a few ways to accomplish this in Sanderson's book, Pro ASP.NET MVC Framework, but haven't had any success.
Also, I've ran across a few similiar questions online, but haven't had any success there either. Seems like I'm missing something rather fundamental.
Currently, I'm trying to use the action method parameters approach. Can someone point out where I'm going wrong or provide a simple example? Thanks in advance!
Using Visual Studio 2008, ASP.NET MVC2 and C#:
What I would like to do is take the data entered in the "Investigator" textbox and use it to filter investigators in the controller. I plan on doing this in the List method (which is already functional), however, I'm using the SearchResults method for debugging.
Here's the textbox code from my view, SearchDetails:
<h2>Search Details</h2>
<% using (Html.BeginForm()) { %>
<fieldset>
<%= Html.ValidationSummary() %>
<h4>Investigator</h4>
<p>
<%=Html.TextBox("Investigator")%>
<%= Html.ActionLink("Search", "SearchResults")%>
</p>
</fieldset>
<% } %>
Here is the code from my controller, InvestigatorsController:
private IInvestigatorsRepository investigatorsRepository;
public InvestigatorsController(IInvestigatorsRepository investigatorsRepository)
{
//IoC:
this.investigatorsRepository = investigatorsRepository;
}
public ActionResult List()
{
return View(investigatorsRepository.Investigators.ToList());
}
public ActionResult SearchDetails()
{
return View();
}
public ActionResult SearchResults(SearchCriteria search)
{
string test = search.Investigator;
return View();
}
I have an Investigator class:
[Table(Name = "INVESTIGATOR")]
public class Investigator
{
[Column(IsPrimaryKey = true, IsDbGenerated = false, AutoSync=AutoSync.OnInsert)]
public string INVESTID { get; set; }
[Column] public string INVEST_FNAME { get; set; }
[Column] public string INVEST_MNAME { get; set; }
[Column] public string INVEST_LNAME { get; set; }
}
and created a SearchCriteria class to see if I could get MVC to push the search criteria data to it and grab it in the controller:
public class SearchCriteria
{
public string Investigator { get; set; }
}
}
I'm not sure if project layout has anything to do with this either, but I'm using the 3 project approach suggested by Sanderson: DomainModel, Tests, and WebUI. The Investigator and SearcCriteria classes are in the DomainModel project and the other items mentioned here are in the WebUI project.
Thanks again for any hints, tips, or simple examples!
Mike
try strongly typing the page to use SearchCriteria to autopost the data like that ex:
public partial class Search: ViewPage<SearchDetails>
This should do it for you (unable to verify this is perfect - typed this from memory):
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult SearchDetails(FormCollection formValues)
{
var txtContents = formValues["Investigator"];
// do stuff with txtContents
return View();
}
1.) Have you looked into ViewModels for your View? In essence that is what your SearchCriteria class is. Make sure you strongly type your view with that model:
<%# Page Title="" Language="C#" MasterPageFile="~/Views/Shared/MyMaster.Master" Inherits="System.Web.Mvc.ViewPage<SearchCritieria>"
Also make sure that you use the HtmlHelper.TextBoxFor method to map this Investigator property to the SearchCritiera model. On Post back your text box value should be there:
'<%=Html.TextBoxFor(model => model.Invesigator)%>'
Good luck!
Also here is a great reference on using ViewModels that I have looked at a lot recently:
http://geekswithblogs.net/michelotti/archive/2009/10/25/asp.net-mvc-view-model-patterns.aspx
Thanks for the tips everyone. For learning purposes, I need to go back and follow the strongly typed route. I'm curious if I would have run into this problem if I would have done that from the beginning.
Until then, the following worked:
Use a submit button
Use this code for the form:
<% using(Html.BeginForm(new { Action = "SearchResults"})) { %> <% } >
Thanks again for you help!
Mike