srpingboot routing problem with thymeleaf - spring-boot

I'm sorry I'm not very specific with the problem this is because I don't know exactly how to discribe the issue, I'm new to sringboot. what I basically want to do is to create a link like http://localhost/admin/countries and http://localhost/admin/countries/add
#Controller
public class CountryController {
#GetMapping("/admin/countries")
public String getCountries() {
return "admin/views/country/index";
}
//add new record
#GetMapping("/admin/countries/add")
public String addCountry() {
return "admin/views/country/add";
}
}
The Link loads correctly without problem, the second link loads but the styling of the page didn't load. I'm using thymeleaf templating so the two file shares the same layout. the index file loads correctly while the add file loads without style
I try to re-route the second link and have something like below and it serve the fike correctly with the style
#Controller
public class CountryController {
//add new record
#GetMapping("/admin/add-country")
public String addCountry() {
return "admin/views/country/add";
}
}
Now I'd like to have something like http://localhost/admin/countries/add, http://localhost/admin/countries/view, http://localhost/admin/countries/update rather than http://localhost/admin/add-country, http://localhost/admin/view-country
What is the cause of this problem and how to fix it
my directory structure look like below
thanks for any help

Related

Spring mapping resources for template Thymeleaf

Spring has problem with mapping items like css, js, img. Problem occured after when I clicked link from template index:
#RequestMapping("/")
public String index(Model model) {
return components.init("index",model).getHeader().getFooter().getSidebar().getRecommended().toString();
}
Link inside template the index looks like that: /places/tags(parameters)
#RequestMapping("/places/tags")
public String index(Model model,#RequestParam(required = false, defaultValue = "eats", value="listOfTag") String listOfTag) {
System.out.println(listOfTag);
return components.init("places",model).getHeader().getFooter().getSidebar().getPlaceForSidebar(listOfTag).toString();
}
After I clicked above link the places site looks not good.
Problem is with the mapping.
No mapping found for HTTP request with URI [/places/assets/css/styles.min.css]
I tried to register resources but nothing to change. I thinking that problem is on the site configuration of Thymeleaf.
I found solution: add before link "/" Topic should be close:)

Send space in route mvc

I have to implement search with MVC3, where user can search any word or words, now if i write only a sigle word its work fine and my route will be like
/search/toy
and toy is recognise by my controller method.
But if i want to search something with space like 'kid toy' then route have a space and in my controller method it doesn't recognise it as a word and throw error like
/search/kids%20toy
Has anyone implement such thing in his project plz help.
Thanks in advance.
Looks like you have an action called "Toy".
// maps to /search/
public class Search : Controller
{
// maps to /search/toy
public ActionResult Toy()
{
}
}
If you haven't modified the default routes at all, you need to use {controller}/{action}/{id}.
(Of course you'll have to look into routing if you want to do different kind of routes. Ask google for ASP.NET MVC routing)
Here's the quickest way:
// maps to /search
public class Search : Controller
{
// maps to /search/for/{id}
public ActionResult For(string id)
{
// search for id
}
}
Which could be used as /search/for/kids%20toy.
Or you can use querystring for parameters named something else than id.
// maps to /search
public class Search : Controller
{
// maps to /search/ by default, check route config
public ActionResult Index(string query)
{
// search for query
}
}
To be able to use {controller}/{action}/{query} or {controller}/{query} you'll have to create a route, but you can address that one by
/search/?query=kids%20toy

Manually parse urls in ASP.NET-MVC-3

I have a Controller with syntax like this:
public class CrudController<TEntity> : Controller
Now if I need a CrudController for Entity User, I just need to extend the CrudController like this
UserCrudController : CrudController<User>
Its working just fine. But, the thing is, the UserCrudController is simply empty. Also, there are some other CrudControllers which are empty too.
Now, I am looking for a way to avoid writing the empty crud controllers. I simply want to create Instances of CrudController with appropriate generic argument. Perhaps by a strict naming convention as described bellow.
The URL will be like: #Html.ActionLink("Create", "UserCrud")
When the URL will be received, it will try to locate the controller named UserCrud (The default thing)
If it fails to locate UserCrud, Crud<User> will be created.
Now, I can do the things I want to do. But exactly where do I do these? Where is the url parsed in mvc?
With help of Craig Stuntz's comment on the question and this question and its accepted answer, I have solved my problem.
I have implemented a custom CotrollerFactory
public class CrudControllerFactory : DefaultControllerFactory {
protected override Type GetControllerType(System.Web.Routing.RequestContext requestContext, string controllerName) {
Type controllerType = base.GetControllerType(requestContext, controllerName);
if(controllerType == null) {
int indexOfEntityEnd = controllerName.LastIndexOf("Crud");
if(indexOfEntityEnd >= 0) {
string entityName = controllerName.Substring(0, controllerName.Length - indexOfEntityEnd - 1);
// Get type of the CrudController and set to controller tye
}
}
return controllerType;
}
}
And then in Application_Start(), I added this line:
ControllerBuilder.Current.SetControllerFactory(typeof(CrudControllerFactory));

Get current controller in view

I have a View - _Edit which lives in News M/V/C.
I reuse the V/M via the CategoryController as:
return PartialView("/Views/News/_Edit.cshtml", model);
How from within the View - _Edit can I alert the controller name?
When I:
alert('#ViewContext. RouteData.Values["controller"].ToString()');
The Value is: News
However, the URL is: /Category/foobar
Is there a way to get the value 'Category' to alert? thanks
I have put this in my partial view:
#HttpContext.Current.Request.RequestContext.RouteData.Values["controller"].ToString()
in the same kind of situation you describe, and it shows the controller described in the URL (Category for you, Product for me), instead of the actual location of the partial view.
So use this alert instead:
alert('#HttpContext.Current.Request.RequestContext.RouteData.Values["controller"].ToString()');
I do it like this:
#ViewContext.RouteData.Values["controller"]
Create base class for all controllers and put here name attribute:
public abstract class MyBaseController : Controller
{
public abstract string Name { get; }
}
In view
#{
var controller = ViewContext.Controller as MyBaseController;
if (controller != null)
{
#controller.Name
}
}
Controller example
public class SampleController: MyBaseController
{
public override string Name { get { return "Sample"; }
}
Other way to get current Controller name in View
#ViewContext.Controller.ValueProvider.GetValue("controller").RawValue
Just use:
ViewContext.Controller.GetType().Name
This will give you the whole Controller's Name
You are still in the context of your CategoryController even though you're loading a PartialView from your Views/News folder.
You can use any of the below code to get the controller name
#HttpContext.Current.Request.RequestContext.RouteData.Values["controller"].ToString();
If you are using MVC 3 you can use
#ViewContext.Controller.ValueProvider.GetValue("controller").RawValue
For anyone looking for this nowadays (latest versions) of ASP.NET Core MVC, you can use:
#Context.Request.RouteValues["controller"].ToString()

T4MVC not generating some Actions for one Controller

I have a situation where T4MVC is generating everything properly (meaning intellisense shows all areas/controllers/actions and everything compiles), but when I run the code, I get a T4MVC was called incorrectly runtime error.
I've investigated the generated files and discovered that for one controller in my project, only actions in the base class are getting the overridden stub actions generated. For other controllers, all actions are being generated. They all have the same set up, described below.
I have a BaseController class that has some shared code (and inherits from Controller). In the Controllers directory (root of project) I have a number of controllers, all which inherit from BaseController.
I then have several Areas. In each Area, I have the same controllers, each inheriting from the controller of the same name in the root Controllers directory.
Running T4MVC (version 2.6.54), everything works fine except for one controller. The odd thing is that intellisense works for the controller, but chokes when the actual action is referenced (in an ActionLink() call).
I manually added one action in particular into the generated code and there was no error.
So my question is, what would cause T4MVC to not generate all code for a controller? The missing actions are all public virtual ActionResult and the actions themselves work fine. The problem controller has the same issue in all Areas.
Some abbreviated code.
/Controllers/BaseController.cs
namespace MyProject.Controllers
{
public abstract partial class BaseController : Controller
{
protected ISession session;
public BaseController()
{
}
// other shared methods/actions
}
}
/Controllers/ActivitiesController.cs (this is the problem controller)
namespace MyProject.Controllers
{
public partial class ActivitiesController : BaseController
{
// for resolving concurrency exceptions
private Activity userValues;
private Activity databaseValues;
public ActivitiesController() : base()
{
ViewBag.ControllerName = "Activities";
}
// this action is causing the problem used like
<li>#Html.ActionLink("Activities", MVC.Areas.Module1.Activities.Index())</li> in a view
public virtual ActionResult Index()
{
return View();
}
}
}
/Areas/Module1/Controllers/ActivitiesController.cs. This is the whole class
namespace MyProject.Areas.Module1.Controllers
{
public partial class ActivitiesController : MyProject.Controllers.ActivitiesController
{
public ActivitiesController() : base()
{
base.currentModule = Modules.Module1;
}
}
}
In case anyone else comes across this I had a similar issue and resulting run-time error message but in a bit different scenario. It was in the RedirectToAction statement at end of a ActionResult method:
RedirectToAction(Edit(id));
The error went away after correcting it to:
RedirectToAction(MVC.[action name].Edit(id));
The error message isn't very intuitive and the suggestion to re-run the custom tool doesn't really help.
Did you make sure to re-run T4MVC to generate based on the latest (Right click .tt file / run custom tool)?
If that's not the problem, I may need to look at a sample app that has the problem to see what's going on.

Resources