ASP.NET MVC 4 get value from different controller - asp.net-mvc

I have a class "Student" and other class "scoresheet".
Each Professor should be able to fill up a scoresheet for each student. I have been able to create, list, edit the scoresheet with using the default scaffolding options.
However, when a professor is directed to homepage/students he is presented with the default option such as create, edit, delete, and i would also like to add a "score" option, that would go to the create option of the scoresheet model/controller.
I was able to do this, but i would like to know how i can pass the StudentID/name to the scoresheet controller in order to know for which student the scoresheet is being created.
Please advise.
Thank you in advance.

You can use AJAX to send the id as a parameter and call the Controller Action

Related

.NET custom authorize attribute (mvc)

In certain Controller I have CRUD methods. In order to access these methods user needs to be logged in. This is why I used [Authorize] attribute for this controller. Now I need additional attribute which would check if item that user wants to view/delete/update belongs to him.
Is it possible and recommended to do this with attribute or you would suggest using check methods inside each method? If you suggest using attribute, could you please provide me some links/instructions?
EDIT:
Ofcourse, if attribute returns false than I don't want to redirect user to login page but show him an error message...
It can be done with a custom Authorize attribute, but it's much cleaner to put the logic inside your controller methods.
The attribute is related to the action being called (the controller class method). On that basis any attribute relating to the user's ownership of the object being manipulated (from your Model) should really be on the entity/class that the user is attempting to manipulate. You'll probably find it easier to validate the user within the Model method rather than using an attribute to achieve this.
In my opinion it is possible, just google for 'Custom Authorize Attribute'.
But maybe it is better to query your database with something like this:
ContextOrSession.Query<Something>.Where(Something.Groups.Intersect(User.Groups).Count>0)

Edit one model on the view page of another - ASP.NET MVC

I am writing a basic blogging application in ASP.NET MVC. I have a Post model which can be displayed via View.aspx. On that page I also want to have a form to submit a comment, but as View.aspx inherits the Post model, I don't know how to have it edit a Comment model.
In your controller you can use whatever model you like. So place a form in your view which points to Post/Comment/{postid} or Comment/Add/{postid}. After you added the model to the database redirect to the previous view.
tsv - create a few partialviews for the comments (strongly typed) and create a couple of methods on the comment controller:
GetComments(int postId)
AddComment(Comment newComment)
in your post view, call the partialview either via $ajax or directly in the page.
jim
The key thing to understand here is when your page 'inherits' a class (Post, in your case), this is purely so that the Model does not need to be cast in any way.
This does not restrict you from referring to other classes within the aspx page, nor does it prevent the page from having a form which posts to another Controller/Action that inherits from a completely different class (Comment, in your case).
Maybe if you posted some example code, we could suggest ways to make it work the way that you want.
As Jim said, you can create the necessary methods in a different or in the same Controller and call <% Html.RenderAction("methodName","ControllerName") %> in your view.aspx which will still inherit the Post Model.
Then, create usercontrols for the form to submit a comment and to display all the comments.

How do I pass a list of integers to an MVC action?

I have an action that depends on a list of integers. My first instinct was to simply declare the action with a List.
I tried declaring the action in the controller as:
public ActionResult EditMultiple(List<int> ids)
and in my View call like so:
<%= Html.ActionLink("EditMultiple", "EditMultiple", new { ids = new List<int> {2, 2, 2} })%>
Although it compiles the List is empty when I put a breakpoint in the action. Anybody know why or have an alternate approach?
Adding more detail about the scenario:
I'm trying to "Edit" multiple entities at the same time. I'm already at the point where I have an application that allows me to create/edit/view information about books in a library. I have a partial view that allows the user to edit information about a single book and save it to the database.
Now I'd like to create a View which allows the user to edit the information about multiple books with a single submit button. I've created an action EditMultiple which just renders the partial for each book (my model for this view is List) and adds the submit button afterwards.
Yes. The default model binder can bind "ids" to any ICollection. But you have to submit multiple parameters with the same name. That eliminates using the helper method "ActionLink". You can use url helper Action and append the ids to the link like so:
Test link
Here's the link from Haack's block.
I dont think
new List<int> {2, 2, 2}
gets properly converted into an POST that is bindable, you want to send
Ids=1&Ids=2&Ids=3
a comma separate list may also work, im not sure, i don't use the crappy default modelbinder.
Why are you doing that anyway? I hope thats pseudocode for something else...

How to design a complex form that requires search results from a different MVC controller

I want to create a form for creating an order. So I have an 'Order' controller. One of the first steps will be to select an existing person to send this order to.
I'm thinking the Create() action method on OrderController will put a new Order object in session. Then I'll need a link that will redirect to another controller, then return a customerID int to this Create() method.
I will have either a SearchController with a FindCustomer() action method, or a Search() action method on the CustomerController.
I have tried the first way. But what I am doing looks pretty messy. Especially considering that I'll need to do this at least one more time on this form, redirecting to the ItemsController to return items to add to the order.
What's the best way to design communication like this between controllers?
I'm not sure why you think you need other controllers for this. In your GET Create action, put the available Customers and Items in to ViewData, and then in your view put some controls for the user to select values.
Then they will be POSTed to your POST Create action, and you can bind & save it in your Order object. You could have a separate action for adding Items to the Order if that gets too complex. But it could still be on the same OrdersController.

asp.net MVC:hierarchical domain model and controllers

My domain model is this: we have a bunch of schools as the root of the "hierarchy". Each school has teachers and courses, and each course has one teacher. I am trying to model this with the logic of the mvc framework and I 'm quite confused. For example, the \school\details\x should give the first page of a school. That should contain a link to a list of its teachers, and a list to each courses.
A list of teachers means that the index action should be parametric to the school the user is looking at: \teacher\id where id is the school. The same with the course list. And then create teacher or course should also be parametric to what school we are looking at:\teacher\create\x where x=school.
How do I carry around the school id? Is there some neat way to do it, or do I need to pass it around all the time, into every view that needs it? It also makes the site URLs very cryptic. I was thinking of a way to make the url structure like {school-alias}\{controller}\{action}\{id}, still I have to find a way to pass around the school. If this is accomplished, then I need to implement some kind of filter that will not allow a user to perform certain actions if the schoolId he is requesting does not match the one in his profile.
I figure that if I 'm carrying the schoolid around the URL, the site is more REST-like, compared to, for example, getting the schoolId from the user's profile.
I would create acronym for every school. For example:
School no. 1 - ABC
School no. 2 - DEF
If i wanted to list teachers, I would write
http://site-address/ABC/teachers/list or just http://site-address/ABC/teachers
To show basic information about school
http://site-address/ABC
The code for routing would be:
routes.MapRoute(
"Default", // Route name
"{acronym}/{controller}/{action}/{id}", // URL with parameters
new {controller = "School", action = "Details", id = ""} // Parameter defaults
);
I would create authorization action filter on teachers,school and classes controller to check if user has access to school defined by acronym parameter in URL. You can check it by comparing filterContext.RouteData.Values["acronym"] with data stored in profile.
Write an extension method to overload rendering of links that extracts the school identifier ( acronym or whatever you choose to use ) from the routing data and adds it to the route values already passed in. This way your action can choose to use the identifier if it is present but is not required to add it to the view data and you do not have to remember to include it in any action links ( you just have to remember to use your action link overload ).
I would make the action link overload quite obviously different so anyone following behind you can see you are doing something unusual. This could be as simple as Html.SchoolActionLink( ...).
For example:
If your url is http://mydomain.com/abc/teachers/list and your route is defined as {school}/{controller}/{action} then the route value dictionary will have the value "abc" at the key "school". The route values can be accessed via HtmlHelper.ViewContext.RouteData.Values.
In the end I 'm answering my own question.
The real solution to this is :Restfull Routing. It implements the functionality in RoR, which is exactly what I need. Too bad this is not a requirement from more people so that it can go into mvc-trunk.

Resources