REST API - Get vs GetBrief/Shell in Controller - rest

So if I have the following entity:
public class Guest
{
public int GuestId { get; set; }
public bool HasCheckedIn { get; set; }
// child/related entities
public Person Person { get; set; }
public Address Address { get; set; }
public Phone Phone { get; set; }
}
Please forgive/correct me if some of the terminology I use is not correct...
Assume we have turned off Navigation Properties which would automatically populate the child entities such as Person and Address.
If my website is calling the WebApi for specific data, sometimes it might need the 'full' Guest object with all of the child entities, in which case it might call the appropriate method in the Business Layer to backfill the object. In other cases, to keep the request light we might just want a 'shell' or 'brief' of the Guest with just the basic data that the underlying table would hold such as HasCheckedIn and all the child entities to just be null.
So what is the suggested approach here for the Api Controller? Should there just be one Persons Controller who's Get method is really a proxy to the GetFull method in the BLL Person class and then have a separate PersonsBrief Controller who's Get method is really a proxy to the GetBrief method in the BLL Person class? Or should this be one method in the Persons Controller which takes in a boolean for IsBrief or something?

Both approaches have merit but it may actually be clearer to separate the summary and details into separate resources. It seems like your use cases between the two variations are distinct, which to me suggests that you should separate your resources accordingly. In other words, implement two separate controller methods, one for "guest details" and another for "guest summary".

Related

Entity Framework with existing classes

I have searched every way I can think of for the answer to this, so forgive me if I have overlooked a post...
I have a project containing model classes that I want to remain database-ignorant (pretend someone handed me the code and said "you're not allowed to modify one character of these classes"). I want to persist these to SQL Server using Entity Framework. So far, I have been able to use the fluent API to map anything that EF couldn't determine logically. But I have hit a block with the following:
public class PhotoPost {
// mapped as Key with fluent API - comes from blog provider
public string PostID { get; set; }
public string Caption { get; set; }
public Collection<Photo> Photos { get; set; }
}
public class Photo {
public string Url { get; set; }
public Image LoadImage() { … }
}
I have a class, PhotoPost, which represents a type of Post on a Blog. The PhotoPost instance has a collection of objects of type Photo, all of which need to be persisted to the database. My problem is that the Photo doesn't really have a primary key. Blog provider doesn't guarantee the Url will not change, and I can't touch this code to add an arbitrary ID. Furthermore, I don't really want an ID. The code that is going to interact with these objects shouldn't/won't know whether these objects came from the blog's API or from a local database (or XML, ...), so I don't really want to clutter up my code with boilerplate in subclassing these objects in another project just to add IDs everywhere (and constructors to create subclasses with IDs from parent classes without, as above) to make EF happy.
Is subclassing to add IDs my only option, or is there a way that I can meet in the middle, between "entity" and "complex type"? (From what I understand, complex types must be one-to-one with their parent entities.)

Entity framework questions about keywords and relationships

I am EF new learner, i have some questions to ask:
1.
I don't understand what does virtual mean in for example one to many, i give an example:
one question can have many options for e.g.
public class Question
{
public int QuestionId { get; set; }
public string Title { get; set; }
public virtual List<Option> Options { get; set; }
}
public class Option
{
public int OptionId { get; set; }
public string OptionText { get; set; }
public virtual Question Question { get; set; }
}
but what does the "2" virtual mean, because if i delete the virtual in this line:
public virtual List<Option> Options { get; set; }, i didn't find any differences, it works well as one to many, so can you explain me very clearly and easily what the 2 virtual mean, if it's override, override what?
2.
I don't know when we should use API fluent, for e.g. the previous one to many ex. without api fluent, it's still a one to many Relationship, so please just tell me when we should use it ? in which occasions for example.
3.
in the API fluent, i know "withmany" and "hasmany" together, they mean "many to many", and what's "withrequired? isoptional? "
I think I can answer following points:
EF define all navigation property virtual, so that EF will at runtime create a new class (dynamic proxy) derived from your Brand class and use it instead. This new dynamically created class contains logic to load navigation property when accessed for the first time. This feature is called lazy loading (or better transparent lazy loading).
See the following link for more detail
Entity Framework 4.1 Virtual Properties
2.When to use fluent API
When working with Code First, you define your model by defining your domain CLR classes. By default, the Entity Framework uses the Code First conventions to map your classes to the database schema. If you use the Code First naming conventions, in most cases you can rely on Code First to set up relationships between your tables based on the foreign keys and navigation properties that you define on the classes. If you do not follow the conventions when defining your classes, or if you want to change the way the conventions work, you can use the fluent API or data annotations to configure your classes so Code First can map the relationships between your tables.
http://msdn.microsoft.com/en-us/data/jj591620.aspx
3.See the following link to know What is .WithRequired and .WithOptional options
What part does the .WithRequired play in an EF Fluent API?

How to add to/update a class collection navigation property in ASP.NET Web API (or REST in general)

This is a design problem specific to a Web API project I'm working on, but it might be a question that's general to REST principles. It's also possible I'm completely overthinking this.
I have a class in Entity Framework that has a child collection of another class:
public abstract class Tracker
{
[Key]
public int ID { get; set; }
[MaxLength(50)]
public string Name { get; set; }
public virtual ICollection<Unit> Units { get; set; }
}
The Unit class looks like this:
public class Unit
{
[Key]
public int ID { get; set; }
[MaxLength(50)]
public string Name { get; set; }
}
I'm working on a Web API that will GET a list of trackers, and GET a list of available units, then add a particular unit to a tracker's list of units. Trackers and Units have their own API controllers and repositories and I'm trying to figure out how to modify them to support creating this association, and what the request would look like.
Is it appropriate to update the Tracker endpoint (/Trackers/1) via PUT to add a new Unit to the list, maybe along with the existing Units? How would I handle that on the back end? I think one of the mental hurdles I have with the PUT approach is - would I include the entire child object in the request body collection property? It wouldn't make sense to, but I'm not sure how it would work otherwise. The assumption (in my case) would be that the Unit being added to the Trackers list would be one that already exists and we're just creating the association. Should I maybe use DTOs for both of these to accomplish this more simply and map them accordingly?
Or would it make more sense to create some new joint DTO like "TrackerUnit" with a corresponding endpoint that I can add new associations to by POSTing to that endpoint (POST /TrackerUnits), then handle the processing in a new controller for it? I would think it would also need to support a DELETE to remove the items. I'm not crazy about this approach since this endpoint wouldn't correspond to any actual resources in my system, but just be used for mapping these associations.
How about creating an endpoint:
/Trackers/{id}/units
and then you can Post a Unit to this endpoint to associate with the Tracker identified by the {id}, or similarly:
DELETE /Trackers/{id}/Units/{unitid}
to remove a Unit.

How to handle model validation when the bound edit model != view model

I have a situation in ASP.NET MVC 2 where I have a form whose fields are based on info supplied by a view model, but whose posted data is a subset of that data represented by a slimmer edit model. I'd like to add simple data annotation validation to the edit model, but since the view is based on the view model, I'm not sure how to proceed.
View model and controller action parameters don't have to be the same.
In your case this means that you may be using a richer model class to generate your view (and maybe even posting more information than needed) but your controller action would only use some information from that posted data to populate a simpler application model object instance. No problem. As long as field naming will suffice to populate properties correctly.
You may have these two classes:
public class User
{
[Required]
public string Username { get; set; }
[Required]
public string Password { get; set; }
}
public class Person: User
{
public string Name { get; set; }
public string Address { get; set; }
}
and then your view would be using Person and your controller action would have a parameter of type User. Fine. It will work.
There's no need for these classes to inherit each other either. I've just made it so in this simple example because this way they both share common property names. But otherwise they don't have to be related in any way shape or form as long as posted field names will be able to model bind to controller action parameter class properties.

MVC2 Modelbinder for List of derived objects

I want a list of different (derived) object types working with the Default Modelbinder in Asp.net MVC 2.
I have the following ViewModel:
public class ItemFormModel
{
[Required(ErrorMessage = "Required Field")]
public string Name { get; set; }
public string Description { get; set; }
[ScaffoldColumn(true)]
//public List<Core.Object> Objects { get; set; }
public ArrayList Objects { get; set; }
}
And the list contains objects of diffent derived types, e.g.
public class TextObject : Core.Object
{
public string Text { get; set; }
}
public class BoolObject : Core.Object
{
public bool Value { get; set; }
}
It doesn't matter if I use the List or the ArrayList implementation, everything get's nicely scaffolded in the form, but the modelbinder doesn't resolve the derived object type properties for me when posting back to the ActionResult.
What could be a good solution for the Viewmodel structure to get a list of different object types handled? Having an extra list for every object type (e.g. List, List etc.) seems to be not a good solution for me, since this is a lot of overhead both in building the viewmodel and mapping it back to the domain model.
Thinking about the other approach of binding all properties in a custom model binder, how can I make use the data annotations approach here (validating required attributes etc.) without a lot of overhead?
Check out the Derived Type ModelBinder in MvcContrib. This allows you to modelbind to derived types through the process of 'typestamping' - which is handled automatically for you when using the RenderTypedPartial(...) helper. MvcContrib partials maintain binding state across partials so the Name/Id prefixes are properly maintained on a deep object graph. If you use other mechanisms like templates, then you'll need to handle the typestamping yourself. This is explained in the documentation page.
Getting back to your questions and how the derived types are resolved with the ModelBinder, you can register the derived type variations with attributes in a mechanism similar to the WCF KnownTypeAttribute or you can do the registration on startup. Either way, these variations are registered once and held onto for performance considerations.
The model binder also solves this problem in a way that does not interfere with data annotation/validation attributes. They will work as you expect them in any other scenario.