Should I provide different views on the same REST entity? - rest

I've seen this that suggest I can build different views based on user:
different json views for the same entity
However in asp web api, one uses a Model class, I can't just add new properties willy-nilly.
So, for example I may have uri:
http://host/api/products/id
Returning the model:
public class Product{
public string Code { get; set; }
public string Description { get; set; }
}
But for another purpose I want to add more information, suppose this is expensive because it joins other data to build the model, or formats the data in a very specific way:
http://host/api/productsspecial/id
Returning the model:
public class ProductSpecial{
public string Code { get; set; }
public string Description { get; set; }
public decimal Price { get; set; } //assume expensive to look up
}
So obviously I have a way to do this, two different controllers, returning different views on the data. My question is, is this OK or is there a better way?
Anyway I could do this for example: http://host/api/products/id?includeprice=true and use that to return the alternative model? And is that a good idea?

I would suggest
GET /host/api/products/{id}?fields=code,description,price
You should avoid complicating your resource URL in the manner you describe. Every possible configuration of values would need a new name: "productsReallySpecial", etc.
The problem with ?includePrice=true is you then have a parameter for every variable you might want to make optional. Your documentation can list the default return values and the available return values.

Related

How to get EF POCOs from System.Data.Entities.DynamicProxies

My question is the same as this one
However, I don't really see a solution there. Lets say I have a simple model with two POCOs, Country and State.
public class Country
{
public string Code { get; set; }
public string Name { get; set; }
}
public class State
{
public string Code { get; set; }
public string Name { get; set; }
public virtual Country Country { get; set; }
}
When I use the repository to .GetStateByCode(myCode), it retrieves a dynamic proxy object. I want to send that over the wire using a WCF service to my client. The dynamic proxy is not a know type so it fails.
Here are my alternatives. I can set ProxyCreationEnabled to false on the context and then my .GetStateByCode(myCode) gives me a POCO which is great. However, the navigation property in the POCO to Country is then NULL (not great).
Should I new up a state POCO and manually populate and return that from the dynamic proxy that is returned from the repository? Should I try to use AutoMapper to map the dynamic proxy objects to POCOs? Is there something I'm totally missing here?
I think the answer from Ladislav Mrnka is clear. The Warnings Still apply. Even with this idea below. Becareful what gets picked Up. He just didnt include , if you want to proceed how to easily get data from Object a to object B. That is question at hand really.
Sample solution
See nuget package ValueInjecter (not the only tool that can do this... but very easy to use)
it allows easy copying of One object to another especially with the same properties and types.
( remember the lazy loading / navigation implications).
So vanilla option is :
var PocoObject = new Poco();
PocoObject.InjectFrom(DynamicProxy); // copy contents of DynamicProxy to PocoObject
but check the default behaviour and consider a custom rule
var PocoObject = new Poco();
PocoObject.InjectFrom<CopyRule>(DynamicProxy);
public class CopyRule : ConventionInjection
{
protected override bool Match(ConventionInfo c)
{
bool usePropertry; // return if the property it be included in inject process
usePropertry = c.SourceProp.Name == "Id"; // just an example
//or
// usePropertry = c.SourceProp.Type... == "???"
return usePropertry;
}
}

Should properties of the model be exposed by the view model?

I have read several articles and tutorials on the MVVM pattern but there is one thing I couldn't find distinct information about. Let's take the following example:
The model contains two fields and properties:
private string username;
public string Username {
get; set;
}
private string password;
public string Password {
get; set;
}
Now, what should the view model contain? Should it only contain an instance of the model or should it also "re-expose" the model's properties?
private Model _model;
public Model Model {
get; set;
}
Or...
private Model _model;
public Model Model {
get; set;
}
public Username {
get { return _model.Username; }
set { _model.Username = value; }
}
I have seen both variants in several articles and now am unsure which way is correct.
There is no general right or wrong answer to this question. It depends on the context and on personal preference.
I personally tend to not expose the model to the view directly. I like to have a ViewModel that is specifically tailored for the view. I don't want to implement anything into model just because the view needs it (and I might be tempted to do so when the the model is exposed to the view).
In my ViewModel, I like to have have as little dependencies on the model as possible. If I can get away with it, I like to have a ViewModel that does not have a direct dependency to the Model at all (and have some external entity/service fill do the mapping).

Entity Framework Code First - Restoring collections of the same type

I'm using Entity Framework Code First. The class i'm trying to create contains two collections (of the same type). I'm having problem recovering my respective collections.
My classes look like this:
public class Destination
{
public int DestinationId { get; set; }
public string Name { get; set; }
public List<Lodging> Lodgings { get; set; }
public List<Lodging> Lodgings2 { get; set; }
}
public class Lodging
{
public int LodgingId { get; set; }
public string Name { get; set; }
public Destination Destination { get; set; }
}
I created a new Destination, then I reopened (closed & opened) the database connection. When I retrieve the destination, my collections (dest.Lodgings and dest.Lodgings2) are null. How do I restore the respective collections? If my class only has one collection of a particular type, I could do the following:
var lodgings = context.Lodgings.Where(l => l.Destination.DestinationId == destId).ToList();
I can see that the relationships are maintained in the database schema (Destination_DestinationId1 and Destination_DestinationId2) but I don't seem to be able to get to them.
Any suggestion would be appreciated.
In addition to using Include (as you've discovered) (which loads the related data from the db at the same time the destination is retrieved) you can also retreive the lodgings after the fact. So if you query for the destination and then you want the lodgings, that's possible. One way is called explicit loading where you will use a Load method. The other is with lazy loading, which requires that your classes be set up a particular way and just the mere mention of the Lodgings property will trigger the call to the database to retrieve them.
there's a great blog post on the Ef team blog about the various ways to load related data with DbContext : http://blogs.msdn.com/b/adonet/archive/2011/01/31/using-dbcontext-in-ef-feature-ctp5-part-6-loading-related-entities.aspx
hth
Julie

MVC 3.0 newbie - how do I set display name?

Consider this class used for DB mapping.
[Bind()]
public class ActiveType
{
[Key()]
public int ID { get; set; }
[Display(Name = "Navn")]
public string Name
{
get;
set;
}
public string Prefix { get; set; }
public string Suffix { get; set; }
}
As you can see, I tried to use the Display annotation to make MVC use that name when it auto-generates entity-framework CRUD pages. However, it ignores it. How do I change this? Is it possible through annotations?
If you are genarating your domain classes it will remove the attributes you have added.
It seems like you are using the domain object in entity framework layer for the model in MVC layer. This is not a good practice. You need to create separate view models (http://blogs.msdn.com/b/simonince/archive/2010/01/26/view-models-in-asp-net-mvc.aspx) for the MVC layer. Because you need to separate the presentation logic from the data layer.
You can use something like AutoMapper to map domain object to view model. http://sourceforge.net/projects/automapper-dn/
The example I provided actually worked, but not for auto-generated EF pages, where it would ignore it in some cases.

What is the best way to model multi-part questions

I am trying to design a subclass that will contain responses to multipart questions and some logic to evaluate/act on them. For example, FoodSurvey would be a subclass of BaseSurvey
BaseSurvey
Name
Date
Submit()
FoodSurvey <- BaseSurvey
DoYouLikeIcecream
IfSoWhatFlavour
WouldYouLikeAFreeSample
SendSample(flavour)
...
FoodSurvey could have several dozen or more questions, and I would need to valdate each answer based on others, as well as run some other processes specific to FoodSurvey (as opposed to CarSurvey) that may depend on multiple answers (ex: SendSample(rockyRoad)).
I have toyed with the idea of a Question class with a Questions collection in each Survey but this quickly started to look like a Survey 'engine' which seemed like it 1.) was overkill, 2.) was error prone and 3.) limited the logic I could use to validate answers.
Are there any accepted best practices regarding designing this type of class?
If it matters, the classes will eventually be used in an ASP.NET website or web application.
I like your approach of having a 'Question' class. In more detail, this model could use a type/object patter - sort of like the relationship between a type and an object. The code could look like this:
class Question
{
public string Text { get; set; }
}
class QuestionAnswer
{
public Question Question { get; set; }
public string Answer { get; set; }
}
interface ISurveyValidator
{
bool Validate(SurveyType type, IEnumerable<QuestionAnswer> answers);
}
class SurveyType
{
public string Name { get; set; }
public IList<Question> Questions { get; set; }
public ISurveyValidator Validator { get; set; }
public Survey CreateSurvey(IEnumerable<QuestionAnswer> answers)
{
if (!this.Validator.Validate(this, answers))
throw new Exception();
return new Survey
{
Type = this,
Date = DateTime.Now,
Answers = answers.ToList()
};
}
}
class Survey
{
public SurveyType Type { get; set; }
public DateTime Date { get; set; }
public IList<QuestionAnswer> Answers { get; set; }
}
This would allow you to provide custom validation for each survey type.
I think you're being too hard on yourself when you say 'overkill'. Thinking about scalability and modularity from the start is good design practice in my books, regardless of project size.
I like the idea of a Question class. You could potentially have a member array of Pattern/RegEx objects (whatever they're called in ASP.NET) and a method that takes a String answer, and walks the array trying to match it. You could include final members for point value, topic, hint, etc. Sounds like a perfect candidate for its own class.
In terms of 'linking questions' based on the response to a previous question, perhaps this could be done as simply as maintaining a list of answers ยป next_question pairings, with a default case for those that 'don't like ice cream". This might be a good use case for a hash table, or even an array of objects of a new class - NextQuestionPair, which includes members for 'answer selected' and 'next question'.
EDIT: Think trees, choosing branches based on answers (or lack thereof)