سؤال

So my problem revolves around calling apphost.ResolveService described in the url below: Calling a ServiceStack service from Razor

I am in my _Layout.cshtml

And obviously the following code works perfectly, but as suggested in the answer in the above url it is sort of silly

SMSGateway.Services.EntityCollectionResponse response = 
    new ServiceStack.ServiceClient.Web.JsonServiceClient(
        "http://localhost:1337/")
        .Get<SMSGateway.Services.EntityCollectionResponse>(
            "/entities");

So that gives me a list of Entities :) But not optimal... so here is my attempt to do it in the correct way

var response = ConsoleAppHost.Instance
    .ResolveService<SMSGateway.Services.EntityService>(
        HttpContext.Current).Get(
            new SMSGateway.Services.EntitiesRequest());

// SMSGateway.Services.EntityCollectionResponse response =
//     base.Get<SMSGateway.Services.EntityService>().Get(
//         new SMSGateway.Services.EntitiesRequest());

foreach (var entity in response.Result)
{
    <li>
        <a href="@entity.MetaLink.Href">
            @Html.TitleCase(entity.Name) entities
        </a>
    </li>
}

Okay so the error I get is the following :

error CS0122: ConsoleAppHost is inaccessible due to its protection level....

Is this expected? I was pondering if this was not a case where I might not be allowed to call this in the _Layout.cshtml file?

Further reading brought me to the article InternalVisibleTo Testing Internal Methods in .NET 2.0

Which I found very interesting :P But no cigar :)

هل كانت مفيدة؟

المحلول

I would recommend you not calling services in a Razor template. A Razor template should be used only to render some markup from a model.

The actual data access should be performed in the ServiceStack service that rendered this template. So in your case you could call another service from the operation:

public object Get(SomeRequestDto message)
{
    var response = this
        .ResolveService<SMSGateway.Services.EntityService>()
        .Get(new SMSGateway.Services.EntitiesRequest()
    );

    return response.Rersult;
}

or you might leave the container to inject the dependent service into the current service so that you don't even need to be using some service locator anti-patterns.

public SomeService: Service
{
    private readonly EntityService entityService;
    public SomeService(EntityService entityService)
    {
        this.entityService = entityService;
    }

    public object Get(SomeRequestDto message)
    {
        var response = this.entityService.Get(new SMSGateway.Services.EntitiesRequest()

        return response.Rersult;
    }
}

and then your Razor view will of course be strongly typed to the corresponding model:

@model IEnumerable<WhateverTheTypeOfTheResultYouWannaBeLoopingThrough>
foreach (var entity in Model)
{
    <li>
        <a href="@entity.MetaLink.Href">
            @Html.TitleCase(entity.Name) entities
        </a>
    </li>
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top