In my Action class, I defined method names as follows:
public String doAddUser(){}
public String doDeleteUser(){}
in Struts.xml i've configured as follows:
<action name="*User" class="MyAction" method="do{1}User"></action>
From URI, if i request like AddUser or DeleteUser, its working. But i want to request like addUser or deleteUser (starts with lowercase letter). How can i acheive this?
URLs are case-sensitive, so the following will make addUser and deleteUser work, but not AddUser and DeleteUser. If you want to support both, you will need to create multiple mappings, but I don't think you should strive for that.
<action name="*User" class="MyAction" method="{1}User"></action>
public String addUser(){}
public String deleteUser(){}
Why i asked this question is, in Struts1.x, we have LookupDispatchAction concept. When user hits one url(for ex, addUser), we can call our defined method with whatever name(ie., doAddUser). In this case, we can solve my issue. But Struts 2.x, there is no possibility like that(as far as i know).
It sounds like you are looking for dynamic method invocation. Basically, if you have an action mapped as myAction, then you can invoke the addUser() method by going to myAction!addUser. myAction!execute is equivalent to the default of just myAction.
Related
Multiple controller types were found that match the URL. This can happen if attribute routes on multiple controllers match the requested URL.
public class my1Controller: Controller
[Route("path/{param1}", Name = "test1")]
public ActionResult myaction1(string param1)
public class my2Controller: Controller
[Route("path/{param2}", Name = "test2")]
public ActionResult myaction2(string param2)
Is there anyway of getting around this? For historical SEO I need to have two similar urls that have a different single string param.
Your URLS are identical, there is no way to distinguish between them, and both controllers/actions match. That is because the parameter name has no value in picking between the two routes
You could use inline constraints applied to the param1 and param2 to help routing pick one of them. Or make sure "path" is different
I have came across an issue where i am unable to find a solution.I am working on a web-application and have to impliment Oauth, things are working fine for me except one issue,in my redirect back URL from Yahoo i am getting several parametersand i need to access few of them in my action class.
Now i can easily create a property in my action class with its getter and setter methods but the name of the property is
openid.response_nonce
and my Eclipse editor will not allow me to name a variable like this.Though one solution is add RequestAware interceptor in my action class and access the parameter.
my Question is can i access it without using RequestAware inteceptor?
There isn't a RequestAware interceptor... There is a Servlet-Config interceptor which will check if your action has one of the following interfaces: ServletContextAware, ServletRequestAware, ServletResponseAware, ParameterAware, RequestAware, SessionAware, ApplicationAware, PrincipalAware.
The Servlet-Config interceptor is part of the default-stack, which you are probably already using. So there is no additional cost or configuration required to use one of the aware interfaces.
That aside, if you have a parameter called "openid.response_nonce" which contains a string, you should be able to refer to it with:
//following not tested, and not checked for syntax errors
private Map openid = new HashMap();
//In Constructor{
oauth.put("response_nonce","");
}
//create BOTH a getter and setter for openid
public getOpenid(){
return openid;
}
public setOpenid(Map openid){
this.openid = openid;
}
Now struts2 should be able to figure out how to set the value... I think, sorry didn't test it. You could always create a class called Openid with a response_nonce property(along with the appropriate getters and setters for that Class)... but I think in this case it might be best to just use RequestAware if you only need that single property.
I think that you maybe looking for the Alias interceptor. http://struts.apache.org/2.0.14/docs/alias-interceptor.html
Regards
All the examples I've seen for overloading usually have only two methods of the same name with different parameters and one using the GET verb while the other uses POST. Is it possible to do two or more overloads on the same method, all with the same verb?
Here's an example of what I'm referring to: Can you overload controller methods in ASP.NET MVC?
I don't think you can overload the same action name with the one verb by default. As that other thread you point to says, you can overload the methods & then use an attribute to change the action that maps to the method, but I'm guessing that's not what you're looking for.
Another option that I've used before (depends on how complex/different your overloads are) is to simply use nullable values for the parameters & effectively merge your different signatures together. So instead of:
public ActionResult DoSomething(int id)...
public ActionResult DoSomething(string name)...
just have:
public ActionResult DoSomething(int? id, string? name)
Not the nicest solution, but if one overload just builds on another then its not too bad a compromise.
One final option that may be worth giving a go (I haven't tried it & don't even know if it'll work, but logically it should), is to write an implementation of the ActionMethodSelectorAttribute that compares the parameters passed in the ControllerContext to the method signature & tries to make a best match (i.e. try to resolve the ambiguity a bit more strictly than the default implementation).
I guess it is not. Since I found that the MVC framework didn't really care what you put in the parameter list, for example, my action is like:
public ActionResult Index(int id) {...}
It is ok to request like this: Domain.com/Index.aspx
or Domain.com/Index.aspx?id=012901
or even Domain.com/Index.aspx?login=938293
Since overloading in programming language means that you select different functions (with same name) using the input parameters, but MVC in this case didn't care about it! So other than ActionVerb overloading, I think it is not ok.
I would love to be able to get some strongly typed way of knowing which action is executing.
To clarify im doing AOP where I only allow access to a given action if the user has rights for that action.
The problem with using a string for determining which rule to check for, is that if some developer renames an action, I wont get a compile error telling me that my rule is broken.
Any ideas??
Develop an attribute that performs your check. Apply the attribute, with any necessary options, to the actions that you want to protect. Write unit tests that check that the actions in question exist and are decorated with your attribute (with the proper options). In your attribute you needn't know what action is executing, just whether the current user passes the tests as configured by your attribute's options.
I have a couple of different attributes that I've derived from AuthorizeAttribute that do exactly this sort of thing.
public class RequiresEmailAttribute : AuthorizeAttribute
{
... implements the logic to test whether the current user
... has an email address and redirects to error view if no
... email address is found
}
[RequiresEmail]
public ActionResult SendEmail( string to )
{
....
}
I have a problem with a sample routing with the preview 5 of asp.net mvc.
In the AccountController I have 2 actions:
public ActionResult Delete()
public ActionResult Delete(string username)
While trying to look for Account/Delete or Account/Delete?username=davide the ControllerActionInvoker throws a exception saying that Delete request is ambiguous between my tow actions methods.
The default route in the global.asax hasn't been changed.
Shouldn't the action invoker understand what's the method to call looking in the parameters list?
Using the preview 4 I hadn't these kind of problem performing the same operation.
Any idea?
Solution found!
With the introduction of the ActionNameAttribute, it's now necessary to filter manually which method to call depending on the request. This is done by the ActionSelectionAttribute.
Full explanation here: http://haacked.com/archive/2008/08/29/how-a-method-becomes-an-action.aspx
I can't say for sure why this is happening. But you might want to consider only having the Delete(string username) action and removing the parameter-less overload.
Because string is nullable my understanding is that simply calling Account/Delete will invoke the action with a null username parameter which you can then test for at the beginning of the action method.
What I'd do is ditch the blank Delete(), and only use Delete(string username)
In your url routing you'd have something similar to "/{Controller}/{Action}/{username}/" ?
If you have "/{Controller}/{Action}/{Id}/" you'd be better off doing Delete(string id) and that way just using the url to handle this "/Account/Delete/davide/"
That said use your default route which should be something like the default Id is ""
Then in your Delete(string id) method have:
public ActionResult Delete(string id)
{
if(string.IsNullOrEmpty(id)) return EmptyID();
// Continue normal Delete method
}
public ActionResult EmptyID()
{
// The method you were going to have on a blank delete.
}
That or just wrap it up in the one method on an if {} else {}
Either way I'd just be going with the one method and doing a default on your username/id in your route of an empty string and handle it that way.
If you want to contact me on further follow up to what I mean, or whatever will help, ping me at andrew# my domain on my info page.
Edit: Ah pretty much what Berko said anyway, I'm not sure how Named Attributes would help - so please post a comment here detailing it for other guys who find the same issues! :)
Its ambiguous because the two controller action are the same post method..
You can only used that in form posting scenario for example you are submitting a form data that uses HTTP post..