Umbraco with MVC Controller - asp.net-mvc-4

I am working on MVC and i started learning Umbraco, I didn't get how to bind the umbraco page with mvc controller get method to show the database values. can anyone suggest any url or video?
Thansk...

What you're looking for is Umbraco route hijacking.
You can read about it here.
https://our.umbraco.org/documentation/reference/routing/custom-controllers
It's easiest to demonstrate with an example : let's say you have a Document Type called 'Home'. You can create a custom locally declared controller in your MVC web project called 'HomeController' and ensure that it inherits from Umbraco.Web.Mvc.RenderMvcController and now all pages that are of document type 'Home' will be routed through your custom controller! Pretty easy right :-) OK so let's see how we can extend this concept. In order for you to run some code in your controller you'll need to override the Index Action.
So, basically, you "simply" need to create a controller named after your document type, so for example, a document type with the name "TextPage" would need a controller called "TextPageController". Now, if you read through the documentation, you'll find that your "TextPageController" will need to inherit from the RenderMvcController. Here's an example how to achieve this.
public class TextPageController : RenderMvcController
{
public ActionResult Index()
{
return View("~/Views/TextPage.cshtml");
}
}

This forum link may help you:
https://our.umbraco.org/forum/developers/razor/38242-Umbraco-MVC4111-Surface-controller-using-an-AJAX-form

Related

Why is mandatory the "Route" attribute on methods of a custom-routed controller?

Consider a fresh Asp.Net Core 2.1 MVC Web app created via the Visual Studio 2017 template. Now, consider a custom view (MyView) and also a controller (ActualController) so that the project structure looks similar to this picture:
The MyView shows nothing special, and it's off the point. However, the page should appear when the user enters an URL like http://(domain)/desired/myview or also via a hyperlink in the home page:
<a asp-area="" asp-controller="Desired" asp-action="MyView">MyView</a>
Now let's focus on the controller, which is a class named differently from what the routing expects:
[Route("desired")]
public class ActualController : Controller
{
[Route("MyView")] //without this the method won't be called
public IActionResult MyView()
{
return this.View();
}
}
From what I know, by decorating the controller with a Route attribute tells the URL resolver to match this class. However, the mapping works only if I explicitly add a (redundant) Route attribute on the target method/action. If I remove it, the path won't be found, and the server returns a 404-error.
The question is: why should be mandatory to decorate with Route the method, even the action is implicitly defined by the method name (as usual)?
NOTE: is rather simple for me to rename the controller class, but I'd like to know what are the reasons behind this behavior.
You are overriding the default route of [controller]/[action] with [Route("desired")]. Since you don't define an action parameter on controller level, all other routes have to be done explicitly.
Changing the top route parameter to [Route("desired/[action]")] should solve it and the method name will be used as parameter. You can still override single actions if you want to name them differently by adding the [Route("")] attribute to them.
Also see the docs (Token replacement in route templates) for further description on the route parameters

How to create controller action for details view

Inherited a Sitefinity site. Need to add a MVC widget for the details view on the news pages.
I found this documentation but I can't make heads or tails of it - maybe it was for a different version. I finally found the UrlkeyPrefix buried deep in the news widget options, but following the instructions of the documentation added "!content" in the middle of my details page URL (which I can't have happening) and still did not display my custom widget.
Does anyone know how to correctly configure the controller to get the widget to show up for the details pages?
I sort of got the example in the documentation to work, except that there's this very annoying "!content" in my URL still
https://mysite/news/!content/2017/08/24/my-article-title
[ActionName("!content")]
public ActionResult Filter()
{
return View("index", InitializeModel());
}
Navigating to the URL sans "!content" just shows the list page.
The nature of MVC is such that you're only able to invoke one action at a time.
Assuming that you're invoking the Details action on the NewsController, the other widget you've placed on the page won't understand how to respond to a Details action unless you do one of two things:
Create a corresponding Details action in your own controller OR
Override HandleUnknownAction to handle what you want to happen when another widget's method is invoked. (better, as it reduces ambiguity)
If you want to invoke your Index action on your custom widget when the Details action is invoked on News:
protected override void HandleUnknownAction(string actionName)
{
this.ActionInvoker.InvokeAction(this.ControllerContext, "Index");
}

ASP.NET WebAPI2 Attribute Routing and SubFolders

I'm using Attribute Routing in WebAPI. My question is more on creating sub-folders under controllers in WebAPI (not in MVC, I'm using Areas for that)
I searched what kind of impact it would cause to the existing routing pattern and mostly they referred like adding custom routing template in WebAPIConfig.cs. But since I'm using AttributeRouting, is it really required to create custom template??
I tested my code and it seems to be working fine without any custom templates and I'm also able to achieve modularization by creating sub-folders under Controllers folder but would like to know the best practice and solution.
No - as you've found you don't need to create custom templates if you're using Attribute Routing.
The underlying method (MapAttributeRoutes) calls into the Controller factory to find all classes that inherit from Controller and then checks those for a Route attribute - so where they sit in the namespace hierarchy shouldn't matter.
If you are trying to mix Attribute and Convention routing and have sub-folders for convention based routes then you will need to define a custom template.
FYI: There is one small 'catcha' that you need to be aware off when (re)organizing your controllers in subfolders using attribute routing. Make sure your controller class has a unique name! Otherwise attribute routing gets confused and will not work. To illustrate:
// File: ~/Controllers/Customers/DetailsController.cs
namespace MyProject.Controllers.Customerss
{
[RoutePrefix("~/api/customers/{id}")]
public class DetailsController: ApiController {
[HttpGet]
public IHttpMessageResult GetItem(int id) {...}
}
}
and
// File: ~/Controllers/Orders/DetailsController.cs
namespace MyProject.Controllers.Orders
{
[RoutePrefix("~/api/orders/{id}")]
public class DetailsController: ApiController {
[HttpGet]
public IHttpMessageResult GetItem(int id) {...}
}
}
Although, cleary having different routes and certainly pointing to different controller classes it will throw off the attribute routing. By changing the controller classes to CustomerDetailsControlller and OrderDetailsController the routing issue resolved itself.

Can Umbraco pass a model to view

I am quite new to this Umbraco MVC.
I need to pass some data bound to a model to my partial view from the GET action method.
This simply is not working in a regular MVC way.
[httpget]
public ActionResult Membership()
{
SupplierMembershipInfoModel mm = new SupplierMembershipInfoModel();
mm.ProductPackage = "sssssssss";
ViewBag.status = Request.QueryString["status"];
return PartialView("MembershipPartial", mm);
}
my view:
#model Umbraco.Web.Models.SupplierMembershipInfoModel
some html.....
<td>#Model.ProductPackage</td>
I don't get data here...and the debug never hits the action. But it hits any POST action method.
I know i am doing something wrong...but just don't know what the mistake is??
Any ideas??
As #Sebastiaan points out, the best place to start is the Umbraco community site. There is documentation specific to your issue here: http://our.umbraco.org/documentation/Reference/Templating/Mvc/child-actions
In a nutshell, you want to display a child action on your page and Umbraco uses SurfaceControllers for this. A SurfaceController is simply a Controller that inherits from Umbraco.Web.Mvc.SurfaceController. This provides you Controller with access to the Umbraco context - see here (http://our.umbraco.org/documentation/Reference/Templating/Mvc/surface-controllers).
Either way, you should read the whole documentation section on templating as it will give you a lot of insight into how Umbraco MVC is managed.

Global Data in ASP MVC 4

I'm writing a site for our poker league. In the _Layout page I would like to include some database information like the next game date and how many games of the season are remaining. I presume _Layout is the best page as I would like this information on ALL pages.
How can I get this entity framework data there? I presume a controller is not the way as _Layout is only a template for other views that use their own controllers.
Any information or resources would really be appreciated.
Thanks in advance,
Paul.
You should create a base controller from which all your controllers inherit.
There you can overwrite the method OnActionExecuting() and load that data from the DB, the cache or whereever and pass it to the Viewbag:
public class ControllerBase {
protected override void OnActionExecuting(ActionExecutingContext ctx) {
Viewbag.LayoutPageData = ...;
}
}
Or you can use a base class for all your Viewmodels and pass the data with the model to the view.
Your Layout page is a view also, so you can strongly type it with a viewmodel class.
You can also use Html.Action like in this sample
http://kazimanzurrashid.com/posts/viewdata-or-viewbag-avoid-dependency-pollution-in-asp-dot-net-mvc-controller
you can display your database information in a partial page exemple "_NextGameDate.cshtml"
then you have to include it in _Layout.cshtml page by :
#Html.Partial("_NextGameDate.cshtml");