ASP.NET MVC Field naming convention for nested objects - asp.net-mvc

I am using ASP.NET MVC 1.0.
I am creating a view to Create a new object of the following class
public class ClassOne
{
public string Name {get; set;}
public string Id {get; set; }
public CaptionItem Caption {get; set;}
}
public class CaptionItem
{
public string CaptionSet {get; set;}
public string Text {get; set;}
}
The view will have fields to input Name, Id and the Text of the caption. On submitting the form the ClassOne object is sent to the controller which is supposed to persist the object in the database.
The question is; what should be the naming conventions used so that I can send the object to the controller as
public ActionResult SaveObject(ClassOne objectToSave)
The challenge is the Caption object

you're right, to get to Text field you have to type Caption.Text :)

Related

Entity Framework using foreign key as only primary key in one to many

I am using Entity Framework code first to design the database.
I have 2 models with One to Many relationship. One "Foo" can have many "FooData" as follows -
public class Foo {
[Key]
public string serialNumber{get; set;}
public int someNumber {get; set;}
public string someName {get; set;}
// Many more properties
// Navigation Collection
public virtual ICollection<FooData> FooDatas{get; set;}
}
public class FooData{
[Key]
[ForeignKey("foo")]
public string SerialNum {get; set;}
public DateTime SomeTime {get; set;}
public byte[] SomeData {get; set;}
// Navigation property
public virtual Foo foo {get; set;}
}
When I try to add a controller for "Foo" in MVC, using "Foo" as a scaffolding model, it gives me this error - "Multiplicity is not valid in Role. Because the Dependent Role refers to the key properties, the upper bound of the multiplicity of the Dependent Role must be 1".
I would appreciate some help here.
Thank you
Because of how you have it defined the same key is used in both so it is a 1-to-1 relationship. If you want a real one to many you will need to add/create another field and set them up as a composite key on the FooData table/entity.
public class Foo {
[Key]
public string serialNumber{get; set;}
public virtual ICollection<FooData> FooDatas{get; set;}
}
public class FooData {
[Key, Column(Order = 0),ForeignKey("foo")]
public string SerialNum {get; set;}
[Key,Column(Order=1)]
public int DataId {get;set;}
public virtual Foo foo {get; set;}
}

Check Lazy Load property has loaded in EF6

I'm using class properties by reflection in some operations so when using DynamicProxy instance it causes to load entire DB. (700+ classes are related with each other).
Is it possible to check if lazy load property loaded or not? Disabling dynamic proxy generation (ProxyCreationEnabled = false) is not usable in my case.
Customer oCustomer = context.get(1);
if(oCustomer.Location.HasLoaded)
do smt..
public class Customer
{
public decimal? Id {get; set;}
public virtual CustomerLocation Location{get; set;}
}
public class CustomerLocation
{
public decimal? Id {get; set;}
public string Detail {get; set;}
}
Looks like you are seeking for DbReferenceEntry<TEntity, TProperty>.IsLoaded or DbReferenceEntry.IsLoaded property:
if (context.Entry(oCustomer).Reference(e => e.Location).IsLoaded)
or
if (context.Entry(oCustomer).Reference("Location").IsLoaded)
For collection type navigation properties, just use .Collection instead of .Reference.

How to map non-primitive members to bytes/JSON with NPoco?

Say I have an object:
class Person {
public int Id {get; set;}
public string Name {get; set;}
public Address HomeAddress {get; set;};
}
class Address {
public string Street {get; set;}
public string City {get; set;}
}
I want/need the above object to be mapped to a single column named Person which has a column named HomeAddress whose content is a JSON (or some custom binary serialization).
How do I tell NPoco Database object to use such mapping?
You would use the [SerializedColumn] attribute on the HomeAddress property of the Person class. This will serialize/deserialize json text that is stored in the column.

Is there a design pattern to standardise the display of multiple models into a single view?

I've tinkered with derived classes, interfaces and viewmodels, but I haven't been able to create quite what I need.
Say we're building a CMS with the following models:
ArticleItem
Title
Summary
Content
NewsItem
Headline
PublishDate
Summary
Content
EventItem
EventTitle
StartDate
EndDate
Content
I'm looking for a way to standardise the display of these into one format / view (e.g. so we can display them all in the same RSS feed). The standardized view might be called HTMLItem and have 3 fields:
Title
Summary
Content
The ArticleItem would translate directly to the HTMLItem, that's straightforward.
For the NewsItem I would like to join the PublishDate and the first 100 characters of the content to create Summary field of HTMLItem.
For the EventItem I would like to combine the StartDate and EndDate to create the Summary field of HTMLItem.
Ultimately I'm looking for the easiest, most efficient way to be able to pass the 3 models into a single view that has been designed to display HTMLItem. My best shot so far has been to create a 'convertor' class for each model, but I can't help feeling that there is a better way to do this.
Any experience, expertise and advice would be much appreciated!
Make a ViewModel with the standarized properties and a constructor for each specialized class:
public class HtmlItemViewModel {
//Properties
public string Title {get; set;}
public string Summary {get; set;}
public string Content {get; set;}
//Constructor inside HtmlItemViewModel for each one of the specialized classes:
public HtmlItemViewModel(ArticleItem item)
{
this.Title = item.Title;
this.Summary = item.Summary;
this.Content = item.Content;
}
public HtmlItemViewModel(NewsItem item)
{
this.Title = item.Headline;
this.Summary = String.Format("{0} - {1}", item.PublishDate, item.Summary.Substring(0,1000));
this.Content = item.Content;
}
public HtmlItemViewModel(EventItem item)
{
this.Title = item.EventTitle;
this.Summary = String.Format("{0} - {1}", item.StartDate, item.EndDate);
this.Content = item.Content;
}
}
Then, on the method you use for your RSS Feed simply pass each entity to the constructor on each individual query. Like this:
//Example controller
public class RssController : Controller {
public ActionResult GetRssFeed(){
//Assuming you have a service for each item type
var articleList = ArticleService.GetArticles().Select(s => new HtmlItemViewModel(s));
var newsItemList = NewsItemService.GetNewsItems().Select(s => new HtmlItemViewModel(s));
var eventItemList = EventItemService.GetEvents().Select(s => new HtmlItemViewModel(s));
articleList.AddRange(newsItemList);
articleList.AddRange(eventItemList);
return articleList;
}
}
You can use Viewmodel Pattern in your project
Models and ViewModels are different. Don't confuse the ViewModel with
the MVVM pattern.
The use of a view model can make the interaction between model and
view more simple. A model can sometimes be over complicated having
other model objects as members, which could have model objects as
member etc..
By using a view model you have a good way to simplify what the view
deals with. This will also filter down what can be seen in
intellisense, so if you have different people developing the models
than those working on the views, creating a simple view model can make
it much easier for those just dealing with the UI.
The simple and most common solution to this is to create a composite view model class. This can be a composed class (containing references to your domain models), or a flattened class, referencing properties from each class individually.
So you could do this:
public class HtmlItemViewModel
{
public ArticleItem ArticleItem {get; set;}
public NewsItem NewsItem {get; set;}
public EventItem EventItem {get; set;}
}
Or this:
public class HtmlItemViewModel
{
//Article Item Properties
public string ArticleTitle {get; set;}
public string ArticleContent {get; set;}
public string ArticleSummary {get; set;}
//News Item Properties
public string Headline {get; set;}
public DateTime PublishDate {get; set;}
public string NewsItemSummary {get; set;}
public string NewsItemContent {get; set;}
//Event Item Properties
public string EventTitle {get; set;}
public DateTime StartDate {get; set;}
public DateTime EndDate {get; set;}
public string EventContent {get; set;}
}
Then, whichever way you choose to construct the view model, you will map the view model properties to the domain model(s) in the controller. You can do this mapping manually
HtmlItemViewModel.ArticleTitle = ArticleItem.ArticleTitle;
//and so on...
Or you can use a third party tool like AutoMapper
I tend to favor the flattened view model in most scenarios as it allows me to only send the data I need, no more, no less. And it also allows me to put my data annotations for input validation on the view model instead of the domain model.

Entity framework code first - map class with List<> of another class to multiple tables?

I'm evaluating EF4 and have a pretty basic question...I think, that I can't seem to find an answer for..
take the following example:
public class Question
{
public string question {get;set;}
public string answer {get; set;}
}
public class Person
{
public string Id {get; set;}
public string Name {get; set;}
public List<Question> Questions {get; set;}
}
Then I have the following tables in the database
Person
(
id,
name
)
Question
(
id,
personId,
question,
answer,
)
Can I use the EF4 code first to map the Person class to the two tables, or do I ahve to restructure my POCO's first so the question class contains the id and personId - which is not something I would like to do.
Can I add something to the OnModelCreating to map the class as I need it to be mapped?
Thanks!
Ok here's what I've done for now - but it requires me having to restructure my question class...
public class Question
{
public int Id {get;set;} /* New */
public int PersonId {get;set;} /* New */
public string question {get;set;}
public string answer {get; set;}
public virtual Person PersonObj {get;set;}
}
public class Person
{
public string Id {get; set;}
public string Name {get; set;}
public List<Question> Questions {get; set;}
}
and added the following in the OnModelCreating event
modelBuilder.Entity<Person>().
HasMany(d => d.Questions).
WithRequired(c => c.Person).
HasForeignKey(c => c.PersonId).
WillCascadeOnDelete();
Not sure it's fully right...but seems to be working for now.

Resources