ServiceStack.Razor PartialViewResult equivalent? - servicestack

Is there a way to return the ASP.NET MVC equivalent of a PartialViewResult (stand-alone partial) in ServiceStack.Razor?
In my service, I would like to return the response DTO as a rendered Partial as opposed to a complete View; again, I just need some rendered HTML snippets for this service.
The use case is to make an AJAX call to a service and then have the service returned the rendered partial.
In one of my views, I just tried the following, but it is still returning the full HTML markup and not just the small snippet.
inside travel.cshtml...
#model TravelScenarioResponse
#Model.Name

You can specify to not use any Layout with #layout "", e.g:
#layout ""
#model TravelScenarioResponse
#Model.Name
Otherwise if you want the same view to be used with multiple layouts and as a partial you can add an Views/Empty.cshtml that just contains:
#RenderBody()
And use that layout in any of the View/Template overrides documented in EmailContacts. E.g. you can decorate your Service or action with a [ClientCanSwapTemplates] attribute, e.g:
[ClientCanSwapTemplates]
public class MyService : Service { ... }
And then the client can specify what view they want to render service with, so you can view a partial by specifying ?Template=Empty on the query string, e.g:
http://razor.servicestack.net/rockstars?Template=Empty
http://razor.servicestack.net/rockstars?View=AngularJS&Template=Empty
http://razor.servicestack.net/rockstars?Template=SimpleLayout

Related

Passing PartialView through child action

I'm new to MVC, and now I'm trying to understand the conception of partial views. So, the question is: Does client fully recieve a a whole markup of new html page, when I'm passing a PartialViewRezult from controller to a View by child action. May be it uses AJAX?
In MVC, If you are returning a PartialView to/from an action method then It will return only markup available in your PartialView. It will not wrap your partial view markup in html or body tag. and There is no ajax involved to render a partial view unless you are using an explicit Ajax call.

Can Thymeleaf access the Spring servletContext?

I wonder if anyone can help. We are in the process of converting a Spring Webflow 2 application from using a jsp based view layer, to a Thymeleaf based view.
For this most part this is OK, but now I'm struggling to get Thymeleaf to access an object that we've put in the servletContext.
So, we have an object that is put in the servletContext as part of a bean (implementing ServletContextAware and InitializingBean)
For the sake of simplicity, lets say it is a string:
public class ReferenceDataBuilder implements ServletContextAware, InitializingBean {
public void setServletContext(ServletContext p_context) {
p_context.setAttribute("referenceData", "test text" );
}
In our jsp based views, we can access the referenceData object like this:
<p><c:out value="${referenceData}"/></p>
By the magic of Spring EL, it knows the various scopes it has access to (servletContext, flowScope, flashScope etc), and (I'm guessing?) searches each scope until it finds a matching property. The result is that:
<p>test text</p>
is rendered within the view.
In our thymeleaf template, we are trying to do the same thing:
<p th:text="${referenceData}"/></p>
But this simply returns an empty string. The view renders an empty string:
<p></p>
(but I think the EL is actually being returned as a null)
I'm pretty sure that if the referenceData object were a property of a scope such as flowScope or flashScope this would work - but its not, its a property of servletContext.
Does anyone know if thymeleaf can access the servletContext via EL? Perhaps theres a different syntax I need to use?
Cheers
Nathan
You could access usual maps via the #ctx object, which is of type SpringWebContext.
For example #ctx.locale, #ctx.httpServletRequest.contextPath, #ctx.servletContext or even #ctx.applicationContext for Spring applicationContext.
You could use direct method invocation
<p th:text="${#ctx.servletContext.getAttribute('referenceData')}">Whatever</p>
or the applicationAttributes variables map
<p th:text="${#ctx.servletContext.applicationAttributes.referenceData}">Whatever</p>
or event simpler using Spring implicit object
<p th:text="${application.referenceData}">Whatever</p>

How to render a template by name?

I am trying to get my head around ServiceStack self-hosted app and the new API.
Adding two views of the same name in separate folders results in an error at startup. Is this not allowed?
Foo\
Index.cshtml
Bar\
Index.cshtml
Is there a way to specify a template via a decorator on a method or directly as a return value? I know about the convention of naming views after DTOs. I prefer to be more explicit or follow a convention closer to Sinatra/Express.
return Render(typeof(Views.Foo.Index), new { Name = "Nelly" });
The ServiceStack's Razor Rockstars website which holds the documentation for Razor support in ServiceStack lists some options for selecting a different template:
If it doesn't follow the convention (i.e. Request or Response DTO name) then you can dynamically specify which view or layout template gets used by returning a decorated HttpResult like:
return new HttpResult(dto) {
View = {viewName},
Template = {layoutName},
};
If you're using a static view (i.e. service always uses the same view) then you can specify what view to use by decorating it with the [DefaultView] attribute
[DefaultView("Rockstars")]
public object Get(Rockstars request) {
...
return responseDto;
}
In either case, if you want it strong-typed you can use something like typeof(RequestDto).Name.
View names must be unique
Unlike MVC, heirachy's does not influence view selection in ServiceStack and because each View Page (i.e. razor pages in the /Views folder) must be unique, you're free to lay them out in any flat or nested folder structure you wish.

What is the difference between doView() and render() functions in Liferay?

What is the actual difference between doView() and render() functions in Liferay? and also what is the difference between renderRequest and resourceRequest?
doView() = to handle render requests when in VIEW mode.
render() = This method invokes the doDispath() method and sets the title of the portlet by using getTitle() method. Then it invokes one of doView(), doEdit(), doHelp(), etc. depending of the portlet mode specified in the RenderRequest.
Again, RenderRequest is when you want to handle requests in the VIEW mode of the portlet. If your portlet uses additional resources to render the view (i.e. images, JavaScript files, etc.) then the JSP that renders the view will use <portlet:resourceURL /> tags to generate valid URLs to those resources. Those URLs will be processed with a pair of ResourceRequest and ResourceResponse objects.
You can override the resource phase though but bear in mind that when you use ResourceRequest/ResourceResponse to serve, the portlet can't change the current portlet mode, window state or render parameters. And also the parameters set on the resource urls are not the render parameters and they are valid to serve only that current resource request.

MVC 3 Layout and Controllers

I m building a MVC 3 applications. The application should be able to display a different layout according to the sub domaine (ex: customer1.mysite.com -> layout1; customer2.mysite.com -> layout2; etc...) it will have also a layout for mobile and IE 6.
I have seen that their is the _ViewStart.cshtml that I can leverage to do the logic to set the layout. But what I don't get is where is the controler for that? Should I write all the code in the view?
An other question with layout how to do you factor out the code for the common behaviours? Do you have a controler for that?
And a last one I have seen the concept of areas in asp.net MVC2 is it obsolete now that we have Razor?
Thank you for your help
Fred
This sounds like a good time to use ViewBag.
The idea is that during OnActionExecuting, you would look up the subdomain and shove it into the ViewBag. This can be done in a custom BaseController from which your other controllers inherit, or from an ActionFilter.
Then, in your _ViewStart, you can write a switch statement on ViewBag to control layout.
For example, here is an ActionFilter that will populate #ViewBag.Subdomain in any of your Razor views, including _ViewStart.cshtml.
public class AddSubdomainToViewDataAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
var subdomain = filterContext.HttpContext.Request.Url.Authority.Split('.').First();
var controller = filterContext.Controller as Controller;
controller.ViewData.Add("Subdomain", subdomain);
}
}
Then, decorate your controllers with this new [AddSubdomainToViewData] attribute.
Finally, in _ViewStart.cshtml, do something like this:
#{
Layout = "~/Views/Shared/" + ((#ViewContext.ViewData["Subdomain"] as String) ?? String.Empty) + "_layout.cshtml";
}
This will use a different Razor layout for each subdomain.
While you could do this in the _ViewStart I think that a better way would be to write a custom view engine in which based on the user agent or the domain include a different layout. Then you would have common controllers and views, only the layout will differ.

Resources