I'm struggling with the design aspect of building this web site, its my first website and I'm not sure of the correct direction i need to take this project in. I've posted on this previously but not done a good job of explaining it. So I'll attempt to do so now.
The Site will be used for submitting "Innovation Ideas" from employees. It will have to connect up to an already existing MS Access Database. There will be two tables in this database that it has to communicate with.
The first one Is the InnovationSubmission Table which which looks similar to this :-
ID(Auto Generated),
Short Description,
Long Description,
Name,
Email Address,
Date(From Date.Time.Now()) - on Submission.
Team Name
Area (Area of Business)
The User will use a Web Form(View) to enter the details above, it will be validated, then saved to the back end database. I have this working in a fashion. The issue has started when I have tried to introduce two DropDownlistsFor contorls based on another table which is below :-
AREA A - Team1, Team3, Team5, Team7
AREA B - Team2, Team4, Team6, Team8
This is just sample Data, there are only two different areas in the table, but there will be over 50 teams split across them. I will be looking to have the Teams dropdownList filter on the value in the Area DropDownlist.
In my Models folder I have created a InnovationSubmission Class, that replicates the table in the database, this class is used as a strongly typed data type in the View representing the Submission Form. Its how i Validate the User input and I pass this class to a c# method that sends the data back using ADO.NET.
I'm struggling with how I should be trying to implement the dropdownlists.
Will I need to create a class similar to the InnovationSubmission Class, to represent the Teams/ Area Table?
Is the table at present structured in the best way for this project?
Can I populate both dropdownlists from the 1 table?
How do I relate the Teams & Area Columns?
Any Help would be greatly appreciated!?!
Would this be the correct way to design my View Model :-
public class MyViewModel
{
public int ID { get; set; }
public string shortDesc { get; set; }
public string longDesc { get; set; }
public string Status { get; set; }
public string originator { get; set; }
public string originatorEmail { get; set; }
public IEnumerable<Area> area { get; set; }
public IEnumerable<Team> team { get; set; }
}
public class Team
{
public string teamName { get; set; }
}
public class Area
{
public string area { get; set; }
}
You seem to be talking about cascading dropdown lists where the values of the second one update based on the selection made in the first one. I have illustrated an example of how this could be achieved in this post. The idea is that you subscribe to the .change event of the first dropdownlist and then trigger an AJAX request to a controller action passing the selected value in which you wold query the database and return a list of possible options.
Related
I'm not sure how to phrase this question correctly but here's an issue I am currently facing in a backend development project.
Suppose I have a table called Users. I create a model called User:
public partial class User
{
public int Id { get; set; }
public string Name { get; set; }
public id JobTitleId { get; set; }
... other fields
}
A user has a Job title which is related to a JobTitles table. The way its structured now is the FE will call an api, lets call it dictionary api which returns a list of objects with the job titles. So, something like this:
[{id: 1, title: 'aa'}, {id: 2, title: 'bb'} ...]
So, based on the jobtitleid that was available, this api will be called and the view will show the title based on the id.
Now, I feel like this is not really efficient since if we have a hundred or thousand job titles, FE will have to parse through each object to match the id.
Is there a better way to display the name of the job title given the ID? I cannot return the job title directly because if the user's job title is not updated but that particular form with the job titles is sent with a PUT request, it will return the name of the job title instead of the ID back to the users table.
Also, the job title will be an autocomplete field on the Frontend which will call an api on the backend when a user inputs the name of the job title, thereby returning the id of that job title back to the Backend when a user is updated with a new job title.
Sorry if Im not clear enough, I can ive more details if required.
have you tried doing something like this?
I am assuming JobTitleId belongs to JobTitles class
public partial class User
{
public int Id { get; set; }
public string Name { get; set; }
public id JobTitleId { get; set; }
[ForeignKey("JobTitleId")]
public JobTitles JobTitles{ get; set; }
}
so as you know classes are object by reference and when you pass the User class to your view, the moment you change the user title from the dropdown it will also change the jobtitleId accordingly
I'm sorry if it's confusing, but I don't really know how to word my question.
My C# class is filled with data from API JSON response, it looks as follows:
[DataContract(Name = "user")]
public class User
{
[DataMember(Name="id")]
public int Id { get; set; }
[DataMember(Name="email")]
public string Email { get; set; }
[DataMember(Name="name")]
public string Name { get; set; }
}
I would like to do things like finding an user from User object list, based on some data I have.
There are tutorials made by Microsoft about working with classes, they imply that I know what's inside by storing just added element in a variable.
My issue is that I need to find the User (specifically id) using email - I don't know how to start on this one.
The other MS doc shows that I can just iterate through all elements of User, and then I suppose I could find the id with a simple if statement?... No way it's optimal, considering there are over thousand entries.
We have c# model class with following fields:
public class BasicDetailsModel
{
public string Name { get; set; }
public string Email { get; set; }
public string Mobile { get; set; }
}
Once user clicks on save button with (Name="x", Email="x#gmail.com", Mobile=989), these details get saved in database. Now, in case user updates any of these fields i.e. Name to "y", we have to send Email,Mobile too although these have not changed.
I have oversimplified the problem here. We have multiple cases where Models have over 20 fields and we are updating more than 5 models through single save click.
How can we update only what's needed and assure everything else already saved remain as it is i.e. in this case client would only send (Name="y") and Database will have (Name="y", Email="x#gmail.com", Mobile=989).
I don't want to make multiple database calls before saving and want flexibility that user remove value from already entered fields i.e. can change Name from "y" to null.
I've been going through this blog and I understand what he is saying, especially regarding the hierarchical structure (walking back along the path).
So
/objects/1/property
Removing property should give you the object with id 1, and removing the id should give you all the objects. Excellent and logical.
But I always expose my data via view models, so,
/objects/list/1 will give me the object list view model of the object with id 1. Or /objects/detail/1 will give me the object detail view model for the object with id 1.
Using this approach I have ended up with a long structure just to get a specific view model! I.e. objects/visualization/analysis/thread. Is this even restful? What I seem to be doing (subconsciously!) is structuring my restful API to match the namespace or module for where this specific view model lives (so in .NET it will be namespace: app.models.object.visualization.analysis).
How best to structure a restful endpoint like this? Is it better to have something like
objects-list/1 and objects-detail/1?
Thanks.
Example:
Sorry, I should have been more clear. I will give a .NET example. Suppose I have a cart class
public class Cart
{
public int CardId { get; set; }
public string CartName { get; set; }
public DateTime Created { get; set; }
public DateTime LastUpdated { get; set; }
public IEnumerable<CartItem> Items { get; set; }
}
With a restful design, I could expose carts as /carts, /carts/1, /carts/1/items and so on. But I always expose view models, not the actual data layer object. I.e.
public class CartListModel
{
public int CartId { get; set; }
public string CartName { get; set; }
}
and
public class CartViewModel
{
public int CartId { get; set; }
public string CartName { get; set; }
public DateTime LastUpdated { get; set; }
public IEnumerable<CartItemViewModel> Items { get; set; }
}
So this way I am only exposing the data that I actually need for a specific purpose. Now at the moment, I am exposing these view models as such /carts/list or /carts/list/1. Also /carts/view and /carts/view/1. So the original question is this restful? Do I infact need a separate endpoint for each view model? So /carts-list and /carts-view, carts-view/1 etc.
Non .NET example
Don't really know what to put here! A view model is a representation of the object, only exposing certain properties necessary to bind to a view.
So suppose my object has the following JSON structure
{
id: 1,
name: 'Cart 1',
lastUpdated: '26-Sep-2014 16:51:23',
items: [
// an array of objects
]
}
For a certain view, like a simple table, I may only need the id and the name. So I expose a restful endpoint that gives me back the following structure
{
id: 1,
name: 'Cart 1'
}
Everything else is unnecessary. For a cart edit page, I will probably need a lot more data than just the id and name. The question is, how do I structure a restful endpoint to expose these different representations of the same object?
URIs are stable
Resources are identified by URIs. The get the object with ID 1, do
GET /objects/1
To get a list of all objects, just
GET /objects
Use content negotiation
What representation of the object 1 is returned by the server is decided by content negotiation. This is done using HTTP headers, not URL path segments or query parameters. Do this:
GET /objects/1
Accept: appliction/vnd.com.example.object.detail+json
By this the client could request something you call the "detail view model".
If the client wants to get the "list view model", you could do
GET /objects/1
Accept: appliction/vnd.com.example.object.list+json
Note
The URL is the same for both requests.
The Accept headers have different values.
Don't use different URIs
Don't do any of these:
GET /objects/1/list: This would request the sub resource called list from object 1.
GET /objects/1/list: This would request another sub resource.
GET /objects/1?model=detail or GET /objects/1?model=list: These are different URIs which identify different resources.
Just try to keep your URL as simple as possible. That means that if your API was a house and you want all clothes of a person named Marie, your URL would be:
API/persons/Marie/clothes
And not:
API/house/persons/Marie/clothes/all
Sorry for the bad examples. Rest is pretty hard to explain.
Ok I've been trying to figure out the best way to do this for a few days, but still haven't come up with a very elegant answer so am hoping I someone can point me in the right direction or give some peer review :)
Basically I have 3 classes (they are different and much more complex than these):
public class Person
{
int ID { get; set;}
string Name { get; set; }
virtual IEnumerable<Place> { get; set; }
}
public class Place
{
int ID { get; set;}
string Name { get; set; }
virtual IEnumerable<Thing> { get; set; }
}
public class Thing
{
int ID { get; set;}
string Name { get; set; }
virtual IEnumerable<Place> { get; set; }
virtual int PersonID { get; set; }
}
So basically you have Persons, who have many Places, which can have many Things which can also appear in multiple Places (trying to reduce having to store duplicates of Things) but only for that Person
What is the best way to setup my ViewModel to handle this? Should I just create everything by itself using Ajax and Json (what I've been doing) or is there a way to handle this type of relationship in a ViewModel and single post back to the server?
Currently I'm doing the following:
Fill out Person form -> ajax save to server, get Person ID
Fill out Place form (including Person's ID) -> ajax save to server, get Place ID
Fill out Thing form (including Person ID and Place IDs in a delimited string
I know there should be an easier way to do this as its kinda bulky, but since its all query string I can't figure it out
You say "kinda bulky," but I think it tends to be more lightweight if you can build an object graph on a form in real time by using AJAX/JSON, probably against a RESTful API, somewhat as you describe.
The alternative is using script (jQuery, JSMVC, Knockout) to build a form and POST the whole sucker at once. I've had to do this in some situations where none of the data should be persisted until the whole graph is committed. The trick here is understanding ModelBinder and how it builds/updates that graph for you.
If this is what you were asking, I can expand on the key points of how ModelBinder deals with complex object graphs and collections.
I answered a similar question about how to handle this using interfaces and partial views.
How to create Asp.Net MVC 3 view model