There are few things not clear to me about ASP.NET MV2.
In database I have table Contacts
with several fields, and there is an additional field XmlFields
of which type is xml
. In that field are stored additional description fields.
There are 4 classes:
Contact
class which corresponds toContact
table and is defined by default when creating LINQ classesContactListView
class which inheritsContact
class and has some additional propertiesContactXmlView
class that contains fields fromXmlFields
fieldContactDetailsView
class which mergesContactListView
andContactXmlView
into one class and this one is used to display data in view pages
ContactListView
class has re-defined some properties from Contact
class (so that I can add [Required]
filter used for validation) - but I get warning message:
'ObjectTest.Models.Contacts.ContactListView.FirstName' hides inherited member 'SA.Model.Contact.FirstName'. Use the new keyword if hiding was intended.
ContactDetailsView
class is also used in a form when creating new contact and adding it to database.
I am not sure if this is correct way, and the warning message confuses me a bit. Any advise about this?
Thanks,
Ile
EDIT
According to Jakob's instructions I tried it from scratch:
[MetadataType(typeof(Person_Validation))]
public partial class Person
{
}
public class Person_Validation
{
[Required]
string FirstName { get; set; }
[Required]
string LastName { get; set; }
[Required]
int Age { get; set; }
}
In Controller I have this:
[HttpPost]
public ActionResult Create(Person person, FormCollection collection)
{
if (ModelState.IsValid)
{
try
{
personRepository.Add(person);
personRepository.Save();
}
catch
{
return View(person);
}
}
return RedirectToAction("Index");
}
View:
<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<Validate.Models.Person>" %>
<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
Create
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<h2>Create</h2>
<% using (Html.BeginForm()) {%>
<%= Html.ValidationSummary(true) %>
<fieldset>
<legend>Fields</legend>
<div class="editor-label">
<%= Html.LabelFor(model => model.FirstName) %>
</div>
<div class="editor-field">
<%= Html.TextBoxFor(model => model.FirstName) %>
<%= Html.ValidationMessageFor(model => model.FirstName) %>
</div>
<div class="editor-label">
<%= Html.LabelFor(model => model.LastName) %>
</div>
<div class="editor-field">
<%= Html.TextBoxFor(model => model.LastName) %>
<%= Html.ValidationMessageFor(model => model.LastName) %>
</div>
<div class="editor-label">
<%= Html.LabelFor(model => model.Age) %>
</div>
<div class="editor-field">
<%= Html.TextBoxFor(model => model.Age) %>
<%= Html.ValidationMessageFor(model => model.Age) %>
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
<% } %>
<div>
<%= Html.ActionLink("Back to List", "Index") %>
</div>
</asp:Content>
When posting new person with no values, nothing happens (page is just reloaded). When posting with some values, person is added to db. I have no idea what am I doing wrong.
EDIT 2
I think that problem is in LINQ which already generated partial class Person
. When I define new partial class Person and click on it and "Go to definition" I get following warnings:
C:\Documents and Settings\Korisnik\My Documents\Visual Studio 2008\Projects\Validate\Validate\Models\DataClasses1.designer.cs - (78, 23) : Validate.Models.Person
C:\Documents and Settings\Korisnik\My Documents\Visual Studio 2008\Projects\Validate\Validate\Models\PersonRepository.cs - (11, 26) : Validate.Models.Person
And this is part of the class generated by LINQ:
[Table(Name="dbo.Persons")]
public partial class Person : INotifyPropertyChanging, INotifyPropertyChanged
{
private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(String.Empty);
private int _PersonID;
private string _FirstName;
private string _LastName;
private string _Age;
...
I am pretty sure that this is the cause but I don't know how to solve this. Any idea?
EDIT 3
Ok, let's go from beginning... so this is folder structure:
Dataclasses1.designer.cs:
#pragma warning disable 1591
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:2.0.50727.3603
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace Validate.Models
{
using System.Data.Linq;
using System.Data.Linq.Mapping;
using System.Data;
using System.Collections.Generic;
using System.Reflection;
using System.Linq;
using System.Linq.Expressions;
using System.ComponentModel;
using System;
[System.Data.Linq.Mapping.DatabaseAttribute(Name="Database1")]
public partial class DataClasses1DataContext : System.Data.Linq.DataContext
{
private static System.Data.Linq.Mapping.MappingSource mappingSource = new AttributeMappingSource();
#region Extensibility Method Definitions
partial void OnCreated();
partial void InsertPerson(Person instance);
partial void UpdatePerson(Person instance);
partial void DeletePerson(Person instance);
#endregion
public DataClasses1DataContext() :
base(global::System.Configuration.ConfigurationManager.ConnectionStrings["Database1ConnectionString"].ConnectionString, mappingSource)
{
OnCreated();
}
public DataClasses1DataContext(string connection) :
base(connection, mappingSource)
{
OnCreated();
}
public DataClasses1DataContext(System.Data.IDbConnection connection) :
base(connection, mappingSource)
{
OnCreated();
}
public DataClasses1DataContext(string connection, System.Data.Linq.Mapping.MappingSource mappingSource) :
base(connection, mappingSource)
{
OnCreated();
}
public DataClasses1DataContext(System.Data.IDbConnection connection, System.Data.Linq.Mapping.MappingSource mappingSource) :
base(connection, mappingSource)
{
OnCreated();
}
public System.Data.Linq.Table<Person> Persons
{
get
{
return this.GetTable<Person>();
}
}
}
[Table(Name="dbo.Persons")]
public partial class Person : INotifyPropertyChanging, INotifyPropertyChanged
{
private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(String.Empty);
private int _PersonID;
private string _FirstName;
private string _LastName;
private string _Age;
#region Extensibility Method Definitions
partial void OnLoaded();
partial void OnValidate(System.Data.Linq.ChangeAction action);
partial void OnCreated();
partial void OnPersonIDChanging(int value);
partial void OnPersonIDChanged();
partial void OnFirstNameChanging(string value);
partial void OnFirstNameChanged();
partial void OnLastNameChanging(string value);
partial void OnLastNameChanged();
partial void OnAgeChanging(string value);
partial void OnAgeChanged();
#endregion
public Person()
{
OnCreated();
}
[Column(Storage="_PersonID", AutoSync=AutoSync.OnInsert, DbType="Int NOT NULL IDENTITY", IsPrimaryKey=true, IsDbGenerated=true)]
public int PersonID
{
get
{
return this._PersonID;
}
set
{
if ((this._PersonID != value))
{
this.OnPersonIDChanging(value);
this.SendPropertyChanging();
this._PersonID = value;
this.SendPropertyChanged("PersonID");
this.OnPersonIDChanged();
}
}
}
[Column(Storage="_FirstName", DbType="NChar(10)")]
public string FirstName
{
get
{
return this._FirstName;
}
set
{
if ((this._FirstName != value))
{
this.OnFirstNameChanging(value);
this.SendPropertyChanging();
this._FirstName = value;
this.SendPropertyChanged("FirstName");
this.OnFirstNameChanged();
}
}
}
[Column(Storage="_LastName", DbType="NChar(10)")]
public string LastName
{
get
{
return this._LastName;
}
set
{
if ((this._LastName != value))
{
this.OnLastNameChanging(value);
this.SendPropertyChanging();
this._LastName = value;
this.SendPropertyChanged("LastName");
this.OnLastNameChanged();
}
}
}
[Column(Storage="_Age", DbType="NChar(10)")]
public string Age
{
get
{
return this._Age;
}
set
{
if ((this._Age != value))
{
this.OnAgeChanging(value);
this.SendPropertyChanging();
this._Age = value;
this.SendPropertyChanged("Age");
this.OnAgeChanged();
}
}
}
public event PropertyChangingEventHandler PropertyChanging;
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void SendPropertyChanging()
{
if ((this.PropertyChanging != null))
{
this.PropertyChanging(this, emptyChangingEventArgs);
}
}
protected virtual void SendPropertyChanged(String propertyName)
{
if ((this.PropertyChanged != null))
{
this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
}
#pragma warning restore 1591
PersonRepository.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel.DataAnnotations;
using System.Web.Mvc;
using Validate.Models;
namespace Validate.Models
{
[MetadataType(typeof(Person_Validation))]
public partial class Person
{
}
public class Person_Validation
{
[Required]
string FirstName { get; set; }
[Required]
string LastName { get; set; }
[Required]
int Age { get; set; }
}
public class PersonRepository
{
private DataClasses1DataContext db = new DataClasses1DataContext();
public IQueryable<Person> FindAllPersons()
{
return db.Persons;
}
public Person GetPerson(int id)
{
return db.Persons.SingleOrDefault(x => x.PersonID == id);
}
public void Add(Person person)
{
db.Persons.InsertOnSubmit(person);
}
public void Delete(Person person)
{
db.Persons.DeleteOnSubmit(person);
}
public void Save()
{
db.SubmitChanges();
}
}
}
/Views/Person/Create.aspx:
<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<Validate.Models.Person>" %>
<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
Create
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<h2>Create</h2>
<%= ViewData["greska"]%>
<% using (Html.BeginForm()) {%>
<%= Html.ValidationSummary(true) %>
<fieldset>
<legend>Fields</legend>
<div class="editor-label">
<%= Html.LabelFor(model => model.FirstName) %>
</div>
<div class="editor-field">
<%= Html.TextBoxFor(model => model.FirstName) %>
<%= Html.ValidationMessageFor(model => model.FirstName) %>
</div>
<div class="editor-label">
<%= Html.LabelFor(model => model.LastName) %>
</div>
<div class="editor-field">
<%= Html.TextBoxFor(model => model.LastName) %>
<%= Html.ValidationMessageFor(model => model.LastName) %>
</div>
<div class="editor-label">
<%= Html.LabelFor(model => model.Age) %>
</div>
<div class="editor-field">
<%= Html.TextBoxFor(model => model.Age) %>
<%= Html.ValidationMessageFor(model => model.Age) %>
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
<% } %>
<div>
<%= Html.ActionLink("Back to List", "Index") %>
</div>
</asp:Content>