Umbraco and MVC and JSON - c#

So I got pulled into a deep end having zero experience in umbraco and a tight deadline.
I don't know how umbraco works and how you integrate your MVC site into it really. A lot of headfuzz to get around.
basically the person I am inheriting it from created a basic controller from MVC and we can call the MVC site as we normally do.
I can also do JSON calls to the controller action which gives us back some data in a ViewModel. Great.
But when you browse to the site using umbraco and navigate to that same page, we run into big problems such as not being able to invoke the JSON call to get the data as it says object not found (in other words, the controller action is not found).
I read about umbraco basically overriding the default MVC routings but... why such a mess? :)
how can I integrate an existing MVC site into umbraco without much pain?
what is the url to call a controller action in umbraco integration?
say we have this:
public JsonResult GetPersonDetail(int id)
{
var vm = new AjaxPersonDetailViewModel(....);
return new JsonResult( Data = vm };
}
I can call this in JQuery like so:
/MyController/GetPersonDetail/1
so how do I do that with Umbraco?

Also try using this scaffolding package as well to get the initial bits for your controller in the right place http://our.umbraco.org/Documentation/Reference/Mvc/scaffolding.

Yes you can just manually create the files that the scaffolding process creates and reference them accordingly however i prefer to use that first then add/tweak the auto files to match what i need

Related

How to separate the view and the controller in an ASP.NET application

I have an ASP.NET application that was developed by "programmers". This application contains all things which you should not do:
Hardcoded settings
Copy/paste anywhere (code not re-used)
Make a lot of small SELECT requests to the DB for each row instead of doing JOIN
Model, view and controller in one function
Etc.
Now, my goal is not to throw everything away and start over, but I want to separate different aspects of the MVC of the application. I do not want to start a new MVC project, I would like to evolve the existing solution into something modular.
For the controller, there is no problem, I can create classes that will manage DB connections, send mails etc. On the other hand I do not know how to separate the view and the controller.
The problem that traditional ASP pages myPage.aspx have an associated file myPage.aspx.vb and in this vb file there are both view management part(page elements, like dropdowns) and also the Business part (controller) which is executed on the button click.
I thought about making a call to a myPageControl.vb class that will contain the business part from the file myPage.aspx.vb, which will call the Model (db, mail, other).
(View: myPage.aspx.vb) -> (Control: myPageControl.vb) -> (Model: Db.vb, Mail.vb)
The problem is: how should I do to modify the page content from the controller, for example change a list value or display a text on it. I have to make a call to the View (to the other direction) and pass by parameter the class MyPage (.asp.vb)
I have already tried to find an answer to my question, but I've found only answers taking about MVC projects.
Does anyone have any idea how I should do it?
Seperation of Concerns was one of the main problems with webforms, and one of the advantages of MVC. In my opinion the best you could probably do is seperate the business logic into classes like you are doing now so code could be reused throughout the application, but completely "seperating" everything may require rebuilding the application as an MVC app.
The only answer I've found to this is to have the controller send the "data to bind to" to the page as XML. then all the page has is its page_load of course, and then a method to receive the XML and update itself from it. You can use smart naming structures so that you can do reflection and autobind from the xml to page elements.
Then on an action, have the page generate an xml of all the elements on it and their values, and send that through a "ProcessAction" method that determines the correct controller and calls the right method on the controller.
But as suggested, doing it over as an MVC project probably makes the most sense if that's the pattern you are going for. What I suggested works, but it will be as much or more work than just starting from scratch with MVC. Besides, remember that "support" for web forms is disappearing soon. It's not in (and won't be in) .NetCore, so it's days are numbered.

AngularJS Accessing C# MVC Index return Object

Morning all,
When I do use angularjs to do a http.get I can store the result
var response = $http.get("somethingUseful")
However, when angularjs handles the routing of the url (specifically the index page)
I've got:
Controller.cs:
public ActionResult Index (){
return View(new FunkyModel())
}
within
Index.cshtml:
#model FunkyModel
can access Model etc..., happy days!
though in
Template.html
what's the easiest way to then access this without doing a JSON.Encode or without having to make a second request?
Thanks in advance!
To be honest - it is not the proper way of using Angular + MVC. You shouldn't expect to share models between back-end and front-end code.
You should use JsonResult and send all the data to the view and let Angular load a view for you. In case it is not possible, another request for necessary data is a viable option(not ideal though).
In my opinion building MVC application with Angular on a front-end is a misunderstanding of concepts behind this technologies. Angular is the best when is used as a engine for SPA(Single Page Application), where you can use its routing features, views loading and many many more.

C# MVC and API in one project

I'm going to create a C# Web Application using MVC. I also want to have an API which mirrors the Web UI. As an example: if I have a web ui to "Create employee" I want a matching API call which does the same. It would take in the same information and follow the same process. I want to avoid duplication of code, so I'm looking for guidance on how to best structure my VS Project, so that I start the project correctly. Where should I put my models, my controllers etc? All suggestions appreciated.
I would use ViewModels for the Views and the Api. This viewmodel is used to return to the browser as JSON or to build the View.
I would then use a library for the code handling and redirect to the libray in the Action methods in the view controller.
The View controller will recieve the ViewModel from the API or normal Action methods. It could pass this viewmodel along to the library or possibly translate it to a datamodel and then pass it to the library. In the same action method the view controller will get a model back from the library and rebuilds the viewmodel.
If you use a ViewModel the Api can easily translate it to and from JSON.

HTML link is not to a valid folder...but it still works?

I'm having some trouble understanding a bit of HTML and was hoping that SO could help me in the process of figuring out what is going on, so that I might be able to do this myself in the future.
The markup is simple :
<p>
GET /api/function: returns list of info from database.
</p>
Now, this works fully and I am trying to understand what is going on. My understanding is that this would go to root directory, find a folder called api, find a function called function and run it.
The problem is that there is no folder called api - so what could be going on here ? I can find the C# function that is actually being called to retrieve the items from the DB, but I cannot figure out how the code calling this might be structured. I have a class which extends DbContext to retrieve information, but I cannot see how this is being called and it is not on the call stack when I insert a breakpoint.
Can anyone give me some information on how I might shed some light on this ?
(Apologies for the very general question, I will give more specifics as I begin to understand what is actually going on!)
There is actually no need for an api folder. It can be a simple route configured that maps a certain URI scheme to some files. It doesn't even have to be files, it can be methods on a class.
For example, in ASP.NET Web API, you have ApiController classes with methods. In your case the method would be called Function or GetFunction or similar.
The route config would contain something like that:
routes.MapHttpRoute("SomeRoute",
"api/{action}",
new { controller = "YourController", action = "Index" });
See the introduction to routes in ASP.NET Web API for more info.
I suggest that you also read the entire series about the ASP.NET WebAPI
"~/api/function" need not be an actual folder in your filesystem. It can be a virtual path defined in your webserver configuration, like web.xml in tomcat.

Using MVC3 with folder structure like regular ASP.NET

So I am reading about building MVC3 projects and there is one thing that seriously bugs me. The folder structure of the project in no way corresponds to the path of the HTTP request. There is a bunch of things I like and would want to use, but having a flat folder structure is not one of them.
Why is this a problem? Well, I see it becoming a problem when building a site with a heavy mix of content pages and various forms/dynamic pages (most of our sites are like that), which would typically be done by different people. It seem it would be too complicated for client-side developers to follow routing rules of dynamic pages and/or creating new ones.
What I would like to understand is if there is way to configure MVC3 application in such a way that:
it follows directory structure for finding controllers without explicit route map for each one
views live in the same folder as corresponding controller
routing magic still works for actions and parameters
For instance I'd like to have a request /fus/ro/dah/ to try to find DahController in the \webroot\fus\ro\dah\ folder and execute its Index action. If not found it would look for RoController with Dah action in the \webroot\fus\ro\ folder, etc.
It is entirely possible that MVC was not meant to be working this way at all and I am just trying to force a square peg into a round hole.
UPDATE:
Looks like I can drop a view file into the desired folder structure, and it will be executed. However layout would not work apparently because it is expecting a controller. Does this mean I have to create a controller for pure content pages? That is a pretty crappy design...
UPDATE 2:
Main issue right now is that creating "fus" folder means that MVC will not even attempt to look for FusController... not under "fus" folder, nor anywhere else. Is it possible to get around that?
For instance I'd like to have a request /fus/ro/dah/ to try to find
DahController in the \webroot\fus\ro\dah\ folder and execute its Index
action. If not found it would look for RoController with Dah action in
the \webroot\fus\ro\ folder, etc.
MVC is not designed for a particular need like this, it is a general framework for building applications using model-view-controller pattern.
If you can't bend the application for the framework you can bend the framework for the application and honestly MVC is very customizable. [As a proof, in the current project (migration from ASP to MVC) that I'm working we have models as xml and no classes also we are using XSLTs for rendering. With a little work we have created custom components like custom view engine, custom validation provider, custom model binder... to make the framework best fit for the application and it does]
MVC is not designed and not forces to use it as it is and you can customize/extend as much you want. In your case you may have to create a
custom controller factory (because you want to customize the way in which the controller is seleced),
custom view engine (because you want to customize where the view is placed)
and may be others.
For custom controller factory you have to extend the DefaultControllerFactory class. There are lot of articles you can find through Google that explains about how to create custom controller factories.
Depending upon the view engine you are using you have to extend the respective one. For ex. if you are using web forms then you have to extend the WebFormsViewEngine and it razor then RazorViewEngine.
For more info. check this link
http://codeclimber.net.nz/archive/2009/04/08/13-asp.net-mvc-extensibility-points-you-have-to-know.aspx
you can mixup Asp.net and Asp.net MVC. as LukLed said, MVC is convention over configuration pattern. if you follow the convention. you dont need to configure. you can check this link for mixing up the asp.net content with MVC3
Mixing Asp.net and Razor
I believe ASP.NET MVC is not meant to be used that way. While you can configure MVC to do it, it is better to keep standard /controller/action/parameters URL format. If you have complex website with many different functionalities, areas may be helpful http://msdn.microsoft.com/en-us/library/ee671793.aspx. Every area get its own set of controllers, models and views, so teams working on different parts of website won't disturb each other.
While it may sound convenient, that framework first searches for DahController and executes Index action, then searches for another one, I find it bad idea. URLs should be clearly defined and Fus controller with Ro action shouldn't just stop working, because someone created RoController with Index action.
Look into using Areas as well. I think that helped me get over my folder structure issues with MVC honestly. So i could use the base folder as my Home details, then i could have a 'Admin' area which was a separate folder, things like that.
How "regular ASP.net" do you want it to be? If you want to do "legacy" ASP.Net Web Forms mixed in with MVC, you certainly can - re: mixing MVC with "file based aspx" - aka "hybrid". At the end of the day, it's all ASP.Net.
This is a standard MVC Application generated by Visual Studio. I've added a folder somedirectory where I want to use the legacy folder/file.ext paradigm and have a default.aspx Web Forms file:
Can I navigate to it via http://foo.com/somedirectory? Yes.
Can I use "pretty urls" too? Yes
Vanilla Global.asax generated by VS, just added MapPageRoute:
....
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
//using "pretty urls" - ordering your routes matter.
routes.MapPageRoute("theWebForm", "legacy", "~/somedirectory/default.aspx");
routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
so now I can navigate to it via http://foo.com/legacy
Just check the order of your routes, and perhaps plan on your naming conventions so you don't have "collisions"...
Hth....

Categories