Optional parameter "Id" is same for all nodes in MvcSiteMapProvide - mvcsitemapprovider

following is my sitemap code :
<mvcSiteMapNode title="Partner" controller="Partner" key="Partner" action="ShowPartners" >
<mvcSiteMapNode title="ISP" controller="ISP" key="ISP" action="ShowPartnersIsps" preservedRouteParameters="Id" >
<mvcSiteMapNode title="Operator" controller="Operator" key="Operator" action="ShowIspsOperators" preservedRouteParameters="Id" >
<mvcSiteMapNode title="Subscriber" controller="Subscriber" key="Subscriber" action="ShowOperatorsSubscribers" preservedRouteParameters="Id" >
<mvcSiteMapNode title="Router" controller="Router" key="Router" action="ShowSubscribersRouters" preservedRouteParameters="Id" />
</mvcSiteMapNode>
</mvcSiteMapNode>
</mvcSiteMapNode>
</mvcSiteMapNode>
following is my route.config
routes.MapRoute(
"GetPartnerRoute",
"Partner/ShowPartners/{search}",
new { controller = "Partner", action = "ShowPartners", Search = UrlParameter.Optional }
);
routes.MapRoute(
"GetISPRoute",
"ISP/ShowPartnersIsps/{Id}/{Search}",
new { controller = "ISP", action = "ShowPartnersIsps", Id = UrlParameter.Optional, Search = UrlParameter.Optional }
);
routes.MapRoute(
"GetOperatorRoute",
"Operator/ShowIspsOperators/{Id}/{Search}",
new { controller = "Operator", action = "ShowIspsOperators", Id = UrlParameter.Optional, Search = UrlParameter.Optional }
);
routes.MapRoute(
"GetSubscriberRoute",
"Subscriber/ShowOperatorsSubscribers/{Id}/{Search}",
new { controller = "Subscriber", action = "ShowOperatorsSubscribers", Id = UrlParameter.Optional, Search = UrlParameter.Optional }
);
routes.MapRoute(
"GetRouterRoute",
"Router/ShowSubscribersRouters/{Id}/{Search}",
new { controller = "Router", action = "ShowSubscribersRouters", Id = UrlParameter.Optional, Search = UrlParameter.Optional }
);
the id parameters is not same for all node.
in above situation.
each node has different "Id" value. which not similar for every node. by renaming "Id" i can achieve what i expected. but i cant change the name of "Id".
so when i goes to child node which having parameter "Id" it sets similar value to its parent node.
following is my code after inspect :
Home
>
Partner
>
ISP
>
Operator
>
Subscriber
>
"268e4984-0923-4db7-8dd3-78564663e4d1" is similar for every node. which should be different.
how can i achieve this. please help

When using preservedRouteParameters, the values are "preserved" from the current request. By definition that means a route value can only be used for a singular purpose (although that purpose can span multiple nodes).
There are 2 ways to overcome this:
Use a different route key for each purpose ({ispId}, {operatorId}, etc).
Instead of using preservedRouteParameters, use the default behavior of MvcSitemapProviderwhich expects a unique node perid`. You can build up the parent-child relationships by using a dynamic node provider.
The first option is more scalable. The second option gives you more control (but only scales to about 10,000 nodes).
Do note that for preservedRouteParameters to work right, you need to put all of the ancestor's route values into the current request. So, for example you must provide ispId for the Operator node. Even though your action method may not require it, the parent node ISP still does for it to build the URL correctly.
See demos of both of these options here: https://github.com/NightOwl888/MvcSiteMapProvider-Remember-User-Position

Related

How to make react-router work with dynamically constructed string

I have a requirement to perform routing based on a dynamically constructed string. Something like "city-homestay-id" where "city" and "id" are dynamically replaced. How would I make it work with react-router.
Ex:
www.xxx.com/atlanta-homestay-12345
Thanks
Simply use <Route path="/:cityId" component={YourComponent} /> for dynamic routing and access Id in YourComponent
const { match: { params } } = this.props;
console.log(params.cityId);

MvcSiteMapProvider Node URL rendered as /#

As the title states, the URL for one of the nodes in the breadcrumb is not correct. I just get a http://localhost/#
Obviously I have something wrong.
I have other, similar structures in the sitemap that are working. Can you tell from this whats missing?
I can post more info if needed.
SiteMap :
<mvcSiteMapNode title="ISP" controller="xxx" action="Index">
<mvcSiteMapNode title="PC" action="Details" preservedRouteParameters="pcId">
<mvcSiteMapNode title="SGD" controller="yyy" action="Details" preservedRouteParameters="pcId, yyyId, editable">
<mvcSiteMapNode title="ESGN" controller="yyy" action="Title" preservedRouteParameters="pcId, yyyId, editable" />
</mvcSiteMapNode>
Actions:
[HttpGet]
[Route("xxx/{pcId:int}/yyy/{yyyId:int}/Details/{editable:bool}")]
public virtual ActionResult Details(int pcId, int yyyId, bool editable)
{
[HttpGet]
[Route("xxx/{pcId:int}/yyy/{yyyId:int}/Title")]
public virtual ActionResult Title(int pcId, int yyyId)
{
Route Map:
routes.MapRoute(
name: "xxx",
url: "xxx/{action}/{pcId}",
defaults: new
{
controller = "xxx",
action = "Index",
pcId = UrlParameter.Optional
}
);
Update: When removing the "editable" parameter it started to work.
Could there be an issue with more than 2 params? or possibly the type or name of the parameter?
Update following debug advice from NightOwl88:
The urlHelper does generate the correct url's
This is my controller code:
[HttpGet]
[Route("TransactionDetails/File/{fileId:int}")]
public virtual ActionResult Index(int fileId)
{
{
var urlHelper = new UrlHelper(new System.Web.Routing.RequestContext(this.HttpContext, this.RouteData));
var url = urlHelper.Action("Index", "Transaction",
new System.Web.Routing.RouteValueDictionary { { "id", 678 } });
System.Diagnostics.Debug.WriteLine(url);
}
{
var urlHelper = new UrlHelper(new System.Web.Routing.RequestContext(this.HttpContext, this.RouteData));
var url = urlHelper.Action("Index", "File",
new System.Web.Routing.RouteValueDictionary {{"fileId", 123}});
System.Diagnostics.Debug.WriteLine(url);
}
I get:
/AdministratorConsole/TransactionDetails/678
and
/AdministratorConsole/TransactionDetails/File/123
So the helper is able to generate a url for me but MvcSiteMapProvider is still not happy.
SiteMap is:
<mvcSiteMapNode title="Transaction Log" controller="TransactionLog" action="Index">
<mvcSiteMapNode title="Transaction Details" controller="Transaction" action="Index" preservedRouteParameters="id">
<mvcSiteMapNode title="File Details" controller="File" action="Index" preservedRouteParameters="id, fileId"> <!--TODO link back to parent not working-->
A # indicates the URL could not be resolved based on the information provided (between the current request and what is in the node configuration). See Why does Default UrlResolver throw an exception for an explanation.
MvcSiteMapProvider resolves the URL through MVC's UrlHelper class, so if you are having trouble, you should use the UrlHelper explicitly to troubleshoot. If you put the below code into a controller and edit it to match the request that is generating a #, you will be able to determine how to resolve the URL correctly. However, unlike in MvcSiteMapProvider, the UrlHelper will return null if the URL cannot be resolved. The most likely reason is that you are missing a route value that you have set as required by the route.
// Using controller and action
var urlHelper = new UrlHelper(new System.Web.Routing.RequestContext(this.HttpContext, this.RouteData));
var url = urlHelper.Action("View", "Videos", new System.Web.Routing.RouteValueDictionary { { "id", 123 } });
// Using controller, action, and route name (similar to #Html.RouteLink())
var urlHelper = new UrlHelper(new System.Web.Routing.RequestContext(this.HttpContext, this.RouteData));
var url = urlHelper.RouteUrl("RouteName", new System.Web.Routing.RouteValueDictionary { { "controller", "Videos" }, { "action", "View" }, { "id", 123 } });

Is it possible to get Page Properties inside CQ dialog listener

I have a page at
/content/admin/mycomp-test/testpage/jcr:content
property
name : validated
type : boolean
value : true
Is it possible to get the above property value inside CQ dialog's
I tried the following code, but it;s not working.
<listeners jcr:primaryType="nt:unstructured"
beforesubmit="function(dialog) {
var compPath = dialog.path;
Resource res= resourceResolver.getResource(compPath);
Node node = res.adaptTo(Node.class);
var prop= node.getProperty('validated').getValue().getString();
CQ.Ext.Msg.alert('valieded : ' + prop);
return false;
}" />
}
The following code will get you what you're asking for:
<listeners jcr:primaryType="nt:unstructured"
beforesubmit="function(dialog) {
var properties = CQ.shared.HTTP.eval(CQ.shared.HTTP.noCaching(dialog.path + '.-1.json'));
var validated = properties.validated;
CQ.Ext.Msg.alert('Validated: ' + validated);
}" />
}
In my opinion, it's better to keep this type of JavaScript in an external file which would be included in a clientlib that only displays in edit mode. You can then call that method from within the dialog. For example:
beforesubmit="function(dialog){ foo.bar.baz(dialog); }"
If you're looking to validate user input, there are better ways. Explore the Widgets API documentation.

How to access other module data table SugarCRM

I am writing logic hook and I need to update 1 module fields by using other module elements.
<?php
class logic_hooks_class {
function after_save_method($bean, $event, $arguments) {
if (!isset($bean->ignore_update_c)||$bean->ignore_update_c === false {
//here I need to get module's reservations element: amount_reserved
//should I load relationship like $bean->load_relationship('reservations'); ??
//need to set total_reserved = amount_reserved;
//by the way amount_reserved might have several values for one reserved
$bean->goods = $bean->amount-$bean->total_reserved;
$bean->ignore_update_c = true;
$bean->save();
}
}
}
?>
You can load the beans for the relationship like this:
$bean->load_relationship('reservations');
$reservations = $bean->reservations->getBeans();
Now one can loop the $reservations and fetch and sum up the wanted value.
Just to clarify how load_relationship works. The parameter for load_relationship should be the link vardef pointing to the name of the relationship. A logical name is the plural name for the module, like reservations.

MVC 5 AttributeRouting Catch All

How do I create a catch all route with the new Attribute routing in MVC
I tried this:
[Route("{pagenode}", Order = 999)]
But when I have a named route like
[Route("contact"]
I get the "Multiple controller types were found that match the URL. This can happen if attribute routes on multiple controllers match the requested URL." error.
This can be done with Attribute Routing if the first "directory" in the path is fixed.
For example, to match anything that hits /questions or /questions/4 or /questions/answers/42 then you would use [Route("questions/{*catchall}"].
You can't do this with Attribute routing, do this the MVC4 way:
Map a route in your routemapper like this:
routes.MapRoute("RouteName","{*url}",new { controller = "YourFancyController", action = "YourAction" });
This will be your catch-all Route.
If you would like to map all the routes to their controller you can do this:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapMvcAttributeRoutes();
AreaRegistration.RegisterAllAreas();
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional });
}
The ability to do this must have changed.
In my default controller, still called 'Home' I have one result method which I want executed for an unrecognised URL structure. The routing attribute is: [Route("{*catchall}")]. This is successfully executed for any old thing.
I have a second method which is always successfully executed based on its route (and I've thrown a few route 'styles' at it to see if it always works). I can only assume that the framework always registers the catch-all route last as this is the behaviour I'm seeing.
This is also a brand new, not configured (except for nuGet packages) MVC 5 project excepting that my methods have been changed to return JsonResult (not even doing their job yet but returning little anonymously typed objects). The catch-all for example returns: Json(new { Message = "Invalid Request" }, JsonRequestBehavior.AllowGet). Yes, yes I set the StatusCode first etc etc, this isn't about MY project ;).
I'm sure I haven't left anything out since there's so little to it but if any clarification is wanted I'll see about adding it.

Resources