redstone-dart / redstone

A metadata driven microframework for Dart.
http://redstone-dart.github.io/redstone
MIT License
342 stars 42 forks source link

app.redirect() just return 302 without real redirection #130

Closed mbayou closed 9 years ago

mbayou commented 9 years ago

Hi,

I work on a wiki project in dart and I search to handle 404 error to redirect on a creation page. But when I use redirect, just get http code 302 without a real redirection... Do you have any idea ?

My code

@app.Group('/wiki')
class HomeController {
...
@app.ErrorHandler(HttpStatus.NOT_FOUND)
  handleNotFoundError() => app.redirect(app.request.requestedUri.path + "/new");
...
}
cgarciae commented 9 years ago

On v0.6 I use redirect just fine, which version are you using?

mbayou commented 9 years ago

Hi,

We have this problem with 0.6.0-beta.1 version yes... we use a trick in javascript to fix it, but if it's works for you, I think the problem is from our utilisation.

cgarciae commented 9 years ago

Let me check. I had a problem with redirect in 0.5 but it was fixed in 0.6, but I havent tested it in error handlers.

cgarciae commented 9 years ago

Out of curiosity, are you rendering html or sending json?

mbayou commented 9 years ago

We render html. What problem occurred in the 0.5 ? Do you think are link ?

To detail little more, to check if redirect work I check the response header and we don't have any field Location, even if set it manually...

cgarciae commented 9 years ago

@mbayou Killing two birds with one shot

  1. I have an example using redirect and works fine, you can see it in...
  2. The redstone mvc plugin example show how to use the most recent version of the plugin. With the mvc plugin you can automatically use your route information to render mustache templates using any object encodable by the mapper plugin.

The MVC plugin does a little more than just render mustache templates using the routes return object and path, it provides a set of shortcuts to avoid common repetition and sponsors certain conventions for the projects structure.

Say you have a structure like this

- lib
  - views
    - master.mustache
    - examples
      - edit.mustache
      - index.mustache
      - new.mustache
      - view.mustache

Then you can use setup a controller using MVC's custom annotations like this to render your templates

@Controller('/examples')
class ExamplesController {

  @DefaultGetView(viewSubPath: '/index')
  Future<List<Example>> index() async {
    ...
    return examples;
  }

  @GetView('/new')
  Future<Example> newExampleForm() async {
    return new Example();
  }

  @Post('/new')
  Future createNewExample(@DecodeForm Example example) async {
    ...
    return redirect('/examples/${example.exampleId}');
  }

  @GetView('/:exampleId', viewLocalPath: '/view')
  Future<Example> getExample(String exampleId) async {
    ...
  }

  @GetView('/:exampleId/edit', viewLocalPath: '/edit')
  editExample(String exampleId) {
    ...
  }

  @Post('/:exampleId/edit', viewLocalPath: '/edit')
  saveExample(String exampleId, @DecodeAny Example example) async {
    ...
    return redirect('/examples/$exampleId');
  }

  @ErrorHandler(404) notFound() => redirect('/examples');
}

There are annotations like @GetJson (and all common variants) that automatically convert to json, you can swap each xxxView with xxxJson or even just xxx without generating compile errors. The .mustache is the default but you can change it to anything (like html) in globally or independently each route.