Why is this IgnoreRoute call matching these requests? - asp.net-mvc-2

I've got a localization httphandler that's running in the context of my ASP.Net MVC2 Content folder (part of what it's doing is compiling .less files that are in /Content/css). My default route for this particular set of requests looks like this:
context.Routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
context.MapRoute(
"Area_default",
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional },
new { controller = new VirtualDirectoryConstraint("VDirectory1") },
new string[] { "Namespace.One.MVC" }
);
(As an aside - I don't think it's relevant, but just in case - the VirtualDirectoryConstraint rejects matches on this route if the request is not coming from the passed-in application path/virtual directory)
With this configuration a call to http://server.net/VDirectory1/Content/css/LessCompiler.axd fails because there's no ContentController class. All well and good.
When I add
context.Routes.IgnoreRoute("{Content}/{*pathInfo}");
that call succeeds, but subsequent calls to
http://server.net/VDirectory1/Localization/ClientScript/en-US.js
and
http://server.net/VDirectory1/Authorization/ClientScript
fail. Looking at Phil Haack's RouteDebugger tool, those calls are matching the Content IgnoreRoute route:
True {Content}/{*pathInfo} (null) (null) (null)
and are therefore not being routed to the LocalizationController and AuthorizationController, respectively.
Clearly I'm misunderstanding something about how the IgnoreRoute is supposed to be used and why that particular IgnoreRoute is matching those requests. What am I missing?

Shouldn't your IgnoreRoute use Content instead of {Content} ?
context.Routes.IgnoreRoute("Content/{*pathInfo}");
At the moment, {Content} is probably being expanded as a variable to nothing, which makes the pathinfo match everything.

Related

Why I don't have to specify verbs() for "GET" for my custom REST action?

I have created a standard yii\rest\ActiveController and added my custom action to it:
public function actionTest($id)
{
return ['test' => $id];
}
I have added a new entry to extraPatterns of rules of yii\web\UrlManager:
'extraPatterns' => [
'GET test/{id}' => 'test',
],
Following this answer, I have also added new verb definition in my REST controller:
public function verbs()
{
$verbs = parent::verbs();
$verbs['test'] = ['GET'];
return $verbs;
}
But it turned out to be not needed. Meaning that I can comment out the above piece of code (the entire method in this case) and the whole new REST route is still working:
What am I missing? Why I don't need to specify this new action / router in verbs() for GET (I figured out that I must do this for other verbs)?
In the referenced question/answer you were working with existing action index that already had rule for yii\filters\VerbFilter to only allow GET or HEAD verbs for that action.
But in case of completely new action test there is no existing rule for VerbFilter. If there is no rule for action the VerbFilter will allow any request. That's why if you don't specify rule for test action any verb set up in router will work. Once you specify the rule for test in verbs() method, only allowed verbs will make it through VerbFilter.

Get newly created id of a record before redirecting page

I would like to retrieve the id of a newly created record using javascript when I click on save button and just before redirecting page.
Do you have any idea please ?
Thank you !
One way to do this in Sugar 7 would be by overriding the CreateView.
Here an example of a CustomCreateView that outputs the new id in an alert-message after a new Account was successfully created, but before Sugar gets to react to the created record.
custom/modules/Accounts/clients/base/views/create/create.js:
({
extendsFrom: 'CreateView',
// This initialize function override does nothing except log to console,
// so that you can see that your custom view has been loaded.
// You can remove this function entirely. Sugar will default to CreateView's initialize then.
initialize: function(options) {
this._super('initialize', [options]);
console.log('Custom create view initialized.');
},
// saveModel is the function used to save the new record, let's override it.
// Parameters 'success' and 'error' are functions/callbacks.
// (based on clients/base/views/create/create.js)
saveModel: function(success, error) {
// Let's inject our own code into the success callback.
var custom_success = function() {
// Execute our custom code and forward all callback arguments, in case you want to use them.
this.customCodeOnCreate(arguments)
// Execute the original callback (which will show the message and redirect etc.)
success(arguments);
};
// Make sure that the "this" variable will be set to _this_ view when our custom function is called via callback.
custom_success = _.bind(custom_success , this);
// Let's call the original saveModel with our custom callback.
this._super('saveModel', [custom_success, error]);
},
// our custom code
customCodeOnCreate: function() {
console.log('customCodeOnCreate() called with these arguments:', arguments);
// Retrieve the id of the model.
var new_id = this.model.get('id');
// do something with id
if (!_.isEmpty(new_id)) {
alert('new id: ' + new_id);
}
}
})
I tested this with the Accounts module of Sugar 7.7.2.1, but it should be possible to implement this for all other sidecar modules within Sugar.
However, this will not work for modules in backward-compatibility mode (those with #bwc in their URL).
Note: If the module in question already has its own Base<ModuleName>CreateView, you probably should extend from <ModuleName>CreateView (no Base) instead of from the default CreateView.
Be aware that this code has a small chance of breaking during Sugar upgrades, e.g. if the default CreateView code receives changes in the saveModel function definition.
Also, if you want to do some further reading on extending views, there is an SugarCRM dev blog post about this topic: https://developer.sugarcrm.com/2014/05/28/extending-view-javascript-in-sugarcrm-7/
I resolved this by using logic hook (after save), for your information, I am using Sugar 6.5 no matter the version of suitecrm.
Thank you !

zend framework this->url get different url on the same page but different url

in application\modules\admin\layouts\scripts\layout.phtml
<?php echo $this->url(array('action'=>'logout','controller'=>'user','module'=>'admin'),null,true);?>
when I visited zfmul/public/admin-cate/ , It return
/zfmul/public/admin-cate/logout
but when I visited zfmul/public/admin/categories, It return
/zfmul/public/admin/user/logout
and the two url is render to the same module, same controller, same action, I wonder why it retrun different result?
I didi some configs in application.ini,
resources.router.routes.admincategories.route = "admin-cate/:action/:id"
resources.router.routes.admincategories.defaults.module = "admin"
resources.router.routes.admincategories.defaults.controller = "categories"
resources.router.routes.admincategories.defaults.action = "index"
resources.router.routes.admincategories.reqs.action = "save|edit|index|new"
resources.router.routes.admincategories.defaults.id = "1"
resources.router.routes.admincategories.reqs.id = "\d+"
When you use $this->url, you're in fact using function url from library/Zend/View/Helper/Url.php, whose 1st line is:
$router = Zend_Controller_Front::getInstance()->getRouter();
Since you declared a custom admincategories route, you now have 2 to access those particular module/controller/actions:
Default - accessible via zfmul/public/admin/categories;
Custom - accessible via zfmul/public/admin-cate/.
Depending on the URL you use to access, the $router variable value will change accordingly and so will the result of the $this->url call as you're experiencing.
Here are a few references to questions on SO that might help you work around that behaviour:
Zend Framework: How to disable default routing?;
Zend framework: Removing default routes.

UriPathExtensionMapping in MVC 4

How do I use UriPathExtensionMapping in MVC4? I've added the mapping in the formatter such that:
MediaTypeMappings.Add(new UriPathExtensionMapping("json", new MediaTypeHeaderValue("application/json"))
But I can't use the extension on my route unless I add a verb, such as:
routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}.{extension}"
);
Then it'll recognize my desired media type, but it also starts expecting "extension" as a parameter on the action. Example:
public object Get(string extension)
{
}
Instead of just:
public object Get()
{
}
How can I resolve this?
Thanks!
I don't remember if I noticed this problem, but it might be because I explicitly specified the default value for the extension like:
var rF = routes.MapHttpRoute(
name: "DefaultApi.v1.format",
routeTemplate: "api/1/{controller}/{action}.{format}/{*id}",
defaults: new { id = RouteParameter.Optional, format = "json", version = 1 }
);
*note format = "json" in the line beginning with defaults.
I did also notice that this sometimes doesn't work on requests with trailing parameters for id, like ~/api/1/values/get.json/4.
I can't repro this problem.
You are right that, to use UriPathExtensionMapping, you will need to specify the {controller}.{ext} in your route, like what you described above. If you only specify the {controller}, and uri looks like ~/home.json, then the controller token will be mapped to home.json, which is probably not what you wanted.
However, you should not need to require an "extension" parameter in your action. If you continue seeing this problem, can you post your entire repro, including your controller, your routes and configuration set up with custom formatter? thank you.

Remove Index from MVC url with routeValue

How can I remove the Index from the MVC url that has a routeValue?
E.g.
http://localhost/Beverage/Index/WhiteWine
to
http://localhost/Beverage/WhiteWine
but still be able to have
http://localhost/Beverage/ShowBeverage/1
You can create a custom route:
MapRoute("My Route Name",
"Beverage/{id}",
new { controller = "Beverage", action = "Index" });
Note that the controller name must be hard-coded in the route, then specified in the defaults to tell MVC which controller to use.
If you take the naive approach and map {controller}/{id}, it will accept any URL of the form a/b, which is not what you want.