servicestackservicestack-razor

ServiceStack Controllerless Razor Views - Return view without executing service


Right now we have a lot of dummy MVC controllers that return simple views with web components (vuejs). I'm trying to refactor this to see if we can use the controllerless razor plugin but I don't want to execute the actual service logic when the route is requested by the browser because the component already does this. An example:

/account/edit/1 is a standard MVC controller -> is associated to a view that has something like this <account edit="1" /> that makes an ajax call to /api/account/get/1 . I want to add the Service Stack Razor engine so that we can just use:

/api/account/get/1 (we would remove the api part or add the alternate route) and this would not execute the logic but would execute the security attributes so we can remove the standard MVC controllers that aren't be used. I know we can add different services for this to get it to work but I would prefer to use the same endpoint and just not execute it but return the razor.

Any ideas?

Not the answer I wanted to hear but essentially we can't do what we want, instead we'll create some dummy service stack services to return the correct views which still eliminates the controllers.


Solution

  • In order to use ServiceStack.Razor's No Ceremony Option where you can return dynamic Razor Views without needing a ServiceStack Service your route needs to match up with the razor page so you wouldn't have a route like:

    /account/get/1
    

    As that would require a Razor Content page at:

    /account/get/1.cshtml
    

    You can instead add it to the queryString like /account/get?id=1 as then you can have a Razor Content page like:

    /account/get?id=1
    

    If you wanted to handle /account/get/1 you'd need a Service that handles that route, e.g:

    [Route("/account/get/{Id}", "GET")]
    class ViewAccount 
    {
        public int Id { get; set; }
    }
    

    Your Service can just return the same Request DTO, e.g:

    public object Get(ViewAccount request) => request;
    

    Which will be convention be able to handle a Razor View located at:

    /Views/ViewAccount.cshtml
    

    With the model:

    @model ViewAccount
    

    Note: It's generally not recommended to have /get in routes, this is normally differentiated by a HTTP GET request so I'd recommend either removing the get and just having:

    [Route("/account/{Id}", "GET")]
    

    Or if you wanted a separate route for Razor views use something other than a HTTP Verb which can be confusing, IMO view is more appropriate for HTML pages, e.g:

    [Route("/account/view/{Id}", "GET")]