2
votes

I'm having a go with the razor functionality in service stack. I have a razor cshtml view working for one of my response DTO's.

I need to access some values from the request DTO in the razor view that have been filled in from some fields from the REST route, so i can construct a url to put into the response html page and also label some form labels.

Is there anyway of doing this? I don't want to duplicate the property from the request DTO into the response DTO just for this html view. Because i'm trying to emulate an existing REST service of another product, i do not want to emit extra data just for the html view.

eg http://localhost/rest/{Name}/details/{Id}

eg

    @inherits ViewPage<DetailsResponse>
   @{

        ViewBag.Title = "todo title";
        Layout = "HtmlReport";
   }

this needs to come from the request dto NOT @Model

<a href="/rest/@Model.Name">link to user</a>
<a href="/rest/@Model.Name/details/@Model.Id">link to user details</a>

1
There's no way other than to add your DTO to the view model ... unless you want to add it to one of the auxiliary objects like the ViewBag, the Page object, the Session, etc.McGarnagle
i'm new to razor. how would i add it to the ViewBag object? Other way I just thought of, is if i detect it is not ?f=json or xml, i could return a wrapper htmlResponseDTO that contains request and response objectsDamian S
Yes, I would go with your idea of a wrapper object that contains both -- ViewBag is not advisable, because isn't not strongly typed and therefore poses maintenance problems.McGarnagle

1 Answers

4
votes

If you want to access the Request DTO it needs to be referenced by either by adding the Request to the Response DTO (which you don't want to do), so the other option is to add it to the IHttpRequest.Items Dictionary which is the preferred way to pass data between your filters and services.

public class MyService : Service {
    public object Any(MyRequest request) {
        base.Request.Items["RequestDto"] = request;
        return MyResponse { ... };
    }
}

Then in your view:

@{
   var myRequest = (MyRequest)base.Request.Items["RequestDto"];
}

Wrapping Re-usable functionality in Request Filters

If you find you need to access the Request DTO in your views a lot, then rather than manually assigning it in each service, you can create a Request Filter Attribute or if you want it assigned all the time in a Global Request Filter.

public class SetRequestDtoAttribute : RequestFilterAttribute {
    public override void Execute(
        IHttpRequest req, IHttpResponse res, object requestDto)
    {
        req.Items["RequestDto"] = requestDto;
    }
}

Then you can add this behavior by decorating the [SetRequestDto] attribute on different levels of granularity on either an Action, Service, Request DTO or base class.