Facebook c# sdk mvc3 canvas issue with CanvasAuthorize - facebook

I'm creating a mvc3 canvas app using facebook c# sdk
The method name is create.
I also do a post and have another create method with [HttpPost] attribute.
When I add the [CanvasAuthorize(Permissions = ExtendedPermissions)] attribute to both the create methods, and a link from another page calls this create method, normally the get method should get called but in this case the post method gets called
But if I comment the post method then it goes to the get method.
Any ideas how to solve this.
Thanks
Arnab

This is because of the canvas authorization posting the access token into the page. The only way around it I've found is to create a different action that deals the post and use that action inside the view as post target. It will look something like this:
// /MyController/MyAction
// Post and Get
[CanvasAuthorize(Permissions = ExtendedPermissions]
public ActionResult MyAction(MyModel data)
{
MyModel modelData = data;
if(data==null)
{
modelData = new MyModel();
}
else
{
modelData = data;
}
return View(modelData);
}
// /MyController/MyActionPost
// POST only
[HttpPost]
[CanvasAuthorize(Permissions = ExtendedPermissions]
public ActionResult MyActionPost(MyModel data)
{
if(Model.IsValid)
{
//Processing code with a redirect at the end (most likely)
}
else
{
return View("MyAction", data);
}
}
Then in your MyAction view:
#using (Html.BeginForm("MyActionPost", "MyController"))
{
<!-- Form items go here-->
<inpuy type="submit" value="Submit" />
#Html.FacebookSignedRequest()
}

I have the same issue. It was doing a GET before, then suddenly when browse to an action with [CanvasAuthorize(Permissions = ExtendedPermissions)] attribute, it's doing a POST instead of a GET.

Related

Loading partial view with an Edit Form doesn't overload correctly

I am trying to load an edit form which is a PartialView, into a div using jQuery. I am overloading the EditUser action. The 1st one is for passing the id and loading the form with existing details. The 2nd one is for posting back the form for save. But it seems to call the 2nd method when I load using jQuery and Url.Action. If I comment out the 2nd EditUser method, then it calls the 1st method. Why is that? How can I make it call the 1st one when I pass staffID? Or is there a better way to implement this Edit form in partial view scenario??
And the CreateUser action works just fine as there is no ambiguity on the overloaded methods as 1 has no parameters and the other has a model as parameter.
Thanks
This is my controller:
public PartialViewResult EditUser(String staffId)
{
User um = userService.GetUserDetails(1, staffId, true);
return PartialView(um);
}
[HttpPost]
public PartialViewResult EditUser(User um)
{
if (!TryUpdateModel(um))
{
ViewBag.updateError = "Edit Failure";
return PartialView("EditUser", um);
}
userService.CreateUpdateUser(um);
return PartialView("ViewUser", um);
}
public PartialViewResult CreateUser()
{
ViewBag.Message = "Create New User";
return PartialView(new User());
}
[HttpPost]
public ActionResult CreateUser(User um)
{
if (!TryUpdateModel(um))
{
ViewBag.updateError = "Create Failure";
return PartialView(um);
}
userService.CreateUpdateUser(um);
return View("Index");
}
This is how I am loading my EditUser partialview:
function menuEdit() {
$('#ActionMenu').hide();
$('#SearchBar').hide();
$('#SearchPanel').hide();
$('#SearchResult').hide();
$('#AddViewEditUser').load("#Url.Action("EditUser","User")", {staffId : sId});
$('#AddViewEditUser').show();
}
According to jQuery .load() "The POST method is used if data is provided as an object; otherwise, GET is assumed." Since you are providing data, .load() is using the method "POST", thus your second EditUser() is being called.

How to redirect in Play Framework?

When I call other action in one action, it also display itself template, in Play 1.1 RC
and when I Redirect("...url") but it does not work, is there someone that can help me?
Just to add to the answers above, here's how you redirect to an external url:
public static void index() {
redirect("http://geeks.aretotally.in");
}
To redirect, you simply call the action. From the example in the documentation:
public static void show(Long id) {
Article article = Article.findById(id);
render(article);
}
public static void edit(Long id, String title) {
Article article = Article.findById(id);
article.title = title;
article.save();
show(id);
}
At the end of the edit action, the call to show(...) will cause a redirect on the client's browser as if they had hit the same URL that routes to the show method.
Since none of these answers provide a general/reusable method to do this, here is my code. This allows you to create any number of redirects in the conf/routes file without creating a controller for each.
Yes, this is trivial, but perhaps it is of use to someone.
conf/routes:
GET /admin Application.redirect(url:'/admin/index.html')
app/controllers/Application.java:
public class Application extends Controller {
public static void redirect(String url) {
redirect(url, true);
}
}
In the play framework, when you call an action, by default it renders the template associated with that action.
For example, a Contoller named Application
public static void index()
Will render
app/views/Application/index.html
To make it render a different view, then you can specify the template as the first parameter in the render method.
So,
renderTemplate("Application/myOtherTemplate.html");
Redirect should only really be used if you are redirecting to a URL outside of your application.

Does renderaction calls its corresponding httpPost Action on submit

I'm a little new to asp.net mvc and I have a question (very basic). I have hacked around but I am not totally sure about this and I could'nt find anything particularly helpful.
Assume that I have 2 controllers A and B and 2 views FullView and PartView
public class AController:...
{
//Renders FullView
public ActionResult Create
{
....
}
[HttpPost]
public ActionResult Create
{
....
}
}
public class BController:...
{
//Renders an Arbitrary partial View (PartView)
public ActionResult Create
{
....
}
//Saves the data of the partial View
[HttpPost]
public ActionResult Create
{
....
}
}
the 1st view (FullView) has the code
<%Html.RenderAction("Create", "B"); %>
my question is on submit will BController's action ([HttpPost] Create) run?
Thank you
That depends on what action you specify in your <form /> tag. This doesn't have anything to do with asp.net mvc. If you use Html.BeginForm() without parameters it will post to the current url (not the create action on BController).
Well 1st thing you could do is toggle some breakpoints in your actions and hit f5.
Second - what action is called purely depends on what url you hit with what http method.
But for your case, when you post form A and controller A processes post you might get into validation problems and that's when you return View() on a post action and that's why form B is rendered via its post method.

ASP.NET MVC 2 controller not cached

I have amaster page that calls render action:
<% Html.RenderAction("CategoryList", "Category", new { selectedCategoryId = Model.selectedCategoryId }); %>
and the action looks like:
[ChildActionOnly]
[OutputCache(Duration = 10, VaryByParam = "none")]
public ActionResult CategoryList(int? selectedCategoryId)
{
CategoryList cl = CategoryManager.GetList();
if (selectedCategoryId.HasValue)
CategoryManager.SetSelectedCategory(cl, selectedCategoryId.Value);
return PartialView(cl);
}
But when i run SQL profiler i see that the GetList() query is always called, meaning the action is not being cached.
Any idea what i'm doing wrong?
Thanks!
It's a child action meaning that it is only a part of the final HTML and cannot be cached. For caching fragments of your HTML checkout this blog post.
its easy, use OutputCacheAttribute.
[OutputCache(Duration=60, VaryByParam="None")]
public ActionResult CacheDemo() {
return View();
}
Take care, Ragims

How do you password protect a page with Wicket?

I want to password protect a webpage in Wicket so the user may only access it if he/she has logged in.
I'd also like the page to show the login page, and then after logging in the original page the user was trying to get to.
How is this done with wicket? I've already created a login page and extended the session class.
The framework-supplied way is to provide an IAuthorizationStrategy instance for your application, e.g., by adding to your Application init() method:
init() {
...
getSecuritySettings().setAuthorizationStrategy(...)
}
A working example of Wickets authorization functionality is on Wicket Stuff here, which demonstrates some reasonably complex stuff. For really simple cases, have a look at the SimplePageAuthorizationStrategy. At a very basic level, this could be used like so (taken from the linked Javadoc):
SimplePageAuthorizationStrategy authorizationStrategy = new SimplePageAuthorizationStrategy(
MySecureWebPage.class, MySignInPage.class)
{
protected boolean isAuthorized()
{
// Authorize access based on user authentication in the session
return (((MySession)Session.get()).isSignedIn());
}
};
getSecuritySettings().setAuthorizationStrategy(authorizationStrategy);
Edit in response to comment
I think the best way forward, if you're just going to use something like SimplePageAuthorizationStrategy rather than that class itself. I did something like this to capture pages that are annotated with a custom annotation:
IAuthorizationStrategy authorizationStrategy = new AbstractPageAuthorizationStrategy()
{
protected boolean isPageAuthorized(java.lang.Class<Page.class> pageClass)
{
if (pageClass.getAnnotation(Protected.class) != null) {
return (((MySession)Session.get()).isSignedIn());
} else {
return true;
}
}
};
Then you'd need to register an IUnauthorizedComponentInstantiationListener similar to what is done in SimplePageAuthorizationStrategy (link is to the source code), which should be something like:
new IUnauthorizedComponentInstantiationListener()
{
public void onUnauthorizedInstantiation(final Component component)
{
if (component instanceof Page)
{
throw new RestartResponseAtInterceptPageException(MySignInPage.class);
}
else
{
throw new UnauthorizedInstantiationException(component.getClass());
}
}
});