1

我在根视图文件夹中添加了RazorPlugina (也尝试了 wwwroot )。这是一个 donet 核心项目。每当浏览到: 会生成以下错误:Test.cshtmlTestGet.cshtml/api/test

ServiceStack 于 2017 年 6 月 3 日下午 4:20:40 生成的 TestGet 快照从原始 url 查看 json 数据源: http://localhost:51550/api/test?其他格式: json xml csv jsv 响应状态错误 CodeNullReferenceExceptionMessageObject 引用未设置为 object.Stack Trace[TestGet: 6/3/2017 4:20:40 PM]: [REQUEST: {}] System.NullReferenceException:你调用的对象是空的。在 ServiceStack.Mvc.RazorFormat.FindView(IEnumerable 1 viewNames) in /opt/lib/teamcity-agent/work/d09206570215629/src/ServiceStack.Mvc/RazorFormat.cs:line 174 at ServiceStack.Mvc.RazorFormat.ProcessRequest(IRequest req, IResponse res, Object dto) in /opt/lib/teamcity-agent/work/d09206570215629/src/ServiceStack.Mvc/RazorFormat.cs:line 138 at System.Linq.Enumerable.Any[TSource](IEnumerable1 source, Func`2 predicate) 在 ServiceStack.Formats.HtmlFormat.SerializeToStream(IRequest req, Object response, IResponse res) 在 /opt/lib/teamcity-agent/work/d09206570215629/ src/ServiceStack/Formats/HtmlFormat.cs:第 63 行错误

其他格式有效(json/etc)。

 public class Test
 {
     public string ExternalId { get; set; }                
 }

  [Authenticate, Route("/test")]
  public class TestGet : IGet, IReturn<Test>
  {
  }

 public class TestService : Service
    {
        public IAutoQueryDb _autoQueryDb { get; set; }
        public IDbConnectionFactory _dbFactory { get; set; }

        public TestService(IDbConnectionFactory dbFactory)
        {
            _dbFactory = dbFactory;
        }

        public Test Get(TestGet request)
        {
            var test = new Test();
            test.ExternalId = "abc";
            return test;
        }

    }

测试.cshtml

@using App.Shared.DomainModel
@model Test

<div>Test</div>

应用主机.cs

using App.DomainServices;
using App.FontEnd.Infrastructure.Configuration;
using App.FontEnd.Infrastructure.Core;
using App.Shared.DomainModel;
using Funq;
using LightInject;
using ServiceStack;
using ServiceStack.Admin;
using ServiceStack.Api.Swagger;
using ServiceStack.Auth;
using ServiceStack.Caching;
using ServiceStack.Configuration;
using ServiceStack.Data;
using ServiceStack.Mvc;
using ServiceStack.OrmLite;
using ServiceStack.Validation;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Threading.Tasks;

namespace App.FrontEnd
{
    public class AppHost : AppHostBase
    {
        /// <summary>
        /// Base constructor requires a Name and Assembly where web service implementation is located
        /// </summary>
        public AppHost()
            : base("TestApi", typeof(CompanyService).GetAssembly())
        {

        }

        /// <summary>
        /// Application specific configuration
        /// This method should initialize any IoC resources utilized by your web service classes.
        /// </summary>
        public override void Configure(Container container)
        {


            this.GlobalRequestFilters.Add((httpReq, httpResp, requestDto) =>
            {
                var currentSession = httpReq.GetSession();
                if (currentSession != null)
                {
                    RequestContext.Instance.Items.Add("CurrentUserName", currentSession.UserName);
                    RequestContext.Instance.Items.Add("CurrentUserId", currentSession.UserAuthId);
                }
            });

            ServiceContainer LightContainer = new ServiceContainer();

            LightContainer.RegisterInstance<IDbConnectionFactory>
            (
                new OrmLiteConnectionFactory(
                    "removed",
                    SqlServer2014Dialect.Provider
                )
            );

            LightContainer.Register<IDbConnection>(c =>
                c.GetInstance<IDbConnectionFactory>().OpenDbConnection(),
                new PerScopeLifetime()
            );

            LightContainer.Register<OrmLiteAppSettings>(c =>
                new OrmLiteAppSettings(c.GetInstance<IDbConnectionFactory>()));           
            LightContainer.Register<ServiceStack.Web.IServiceGatewayFactory>(x => new ApiServiceGatewayFactory());
            container.Adapter = new LightInjectAdapter(LightContainer);

            var settings = LightContainer.GetInstance<OrmLiteAppSettings>();
            settings.InitSchema();
            AppSettings = new MultiAppSettings(
                settings
            );

            container.Register<ICacheClient>(new OrmLiteCacheClient
            {
                DbFactory = LightContainer.GetInstance<IDbConnectionFactory>()
            });
            var cacheclient = container.Resolve<ICacheClient>();
            cacheclient.InitSchema();

            AuthConfig(container, AppSettings);

            Plugins.Add(new RegistrationFeature());
            Plugins.Add(new SwaggerFeature());
            Plugins.Add(new RequestLogsFeature());
            Plugins.Add(new PostmanFeature());
            Plugins.Add(new CorsFeature(allowCredentials: true));
            Plugins.Add(new ValidationFeature());

            Plugins.Add(new RazorFormat());



            OrmLiteConfig.InsertFilter = (dbCmd, row) =>
            {
                var auditRow = row as CoreModel;
                if (auditRow != null)
                {
                    var currentDate = DateTime.UtcNow;
                    var insertUserId = RequestContext.Instance.Items["CurrentUserId"] as string;

                    auditRow.Id = Guid.NewGuid();
                    auditRow.CreatedDate = currentDate;
                    auditRow.CreatedBy = insertUserId;
                    auditRow.UpdatedDate = currentDate;
                    auditRow.UpdatedBy = insertUserId;
                }
            };

            OrmLiteConfig.UpdateFilter = (dbCmd, row) =>
            {
                var auditRow = row as CoreModel;

                if (auditRow != null)
                {
                    var updateUserId = RequestContext.Instance.Items["CurrentUserId"] as string;
                    auditRow.UpdatedDate = DateTime.UtcNow;
                    auditRow.UpdatedBy = updateUserId;
                }
            };

            var aq = new AutoQueryFeature { MaxLimit = 100, EnableAutoQueryViewer = true };
            aq.ImplicitConventions.Add("%neq", aq.ImplicitConventions["%NotEqualTo"]);
            aq.ImplicitConventions.Add("%eq", "{Field} = {Value}");
            Plugins.Add(aq);
            Plugins.Add(new AdminFeature());

            SetConfig(new HostConfig
            {
                HandlerFactoryPath = "api",
                DebugMode = true
            });

            container.CheckAdapterFirst = true;

            //Set up service stack validators
            container.ValidatorsSetup();
        }

        public void AuthConfig(Container container, IAppSettings settings)
        {
            Plugins.Add(new AuthFeature(() => new AuthUserSession(),
                new IAuthProvider[] {
                    new CredentialsAuthProvider(AppSettings),
                    new JwtAuthProvider(AppSettings)
                    {
                        AuthKeyBase64 = "abcdefgh"
                    },

                    new BasicAuthProvider()
            }));



            var authRepo = CreateOrmLiteAuthRepo(container, settings);


        }

        private static IUserAuthRepository CreateOrmLiteAuthRepo(Container container, IAppSettings appSettings)
        {
            //Store User Data into the referenced SqlServer database
            container.Register<IAuthRepository>(c =>
                new OrmLiteAuthRepository(c.Resolve<IDbConnectionFactory>()));

            //Use OrmLite DB Connection to persist the UserAuth and AuthProvider info
            var authRepo = (OrmLiteAuthRepository)container.Resolve<IAuthRepository>();
            //If using and RDBMS to persist UserAuth, we must create required tables
            if (appSettings.Get("RecreateAuthTables", false))
                authRepo.DropAndReCreateTables(); //Drop and re-create all Auth and registration tables
            else
                authRepo.InitSchema(); //Create only the missing tables

            return authRepo;
        }
    }
}
4

1 回答 1

1

我创建了一个最小的可验证 MVC 测试项目来模拟您的配置,该配置按预期工作:https ://github.com/NetCoreApps/scratch/tree/master/src/RazorApi

它包括相同的 Test Services,(无[Authenticate]属性):

public class Test
{
    public string ExternalId { get; set; }
}

[Route("/test")]
public class TestGet : IGet, IReturn<Test>
{
}

public class TestService : Service
{
    public Test Get(TestGet request)
    {
        var test = new Test { ExternalId = "abc" };
        return test;
    }
}

以及仅设置并注册 ServiceStack插件的最小 AppHost 配置HandlerFactoryPathapiRazorFormat

public class AppHost : AppHostBase
{
    public AppHost() 
        : base("ServiceStack + .NET Core", typeof(MyServices).GetTypeInfo().Assembly) {}

    public override void Configure(Funq.Container container)
    {
        SetConfig(new HostConfig
        {
            HandlerFactoryPath = "api",
            DebugMode = true,
        });

        Plugins.Add(new RazorFormat());
    }
}

Test.cshtml/Views/Test.cshtml中维护:

@model Test
@{
    Layout = "_Layout";
}

<h1>Test.cshtml</h1>

<p>@Model.ExternalId</p>

调用时执行的 Razor 视图按预期工作:

http://localhost:5000/api/test

当重命名以匹配请求 DTO 时,这也有效TestGet.cshtml

由于问题似乎特定于您的项目,我会将您的布局与裸RazorApi Github 项目进行比较,看看您是否可以找到任何差异,如果失败,我建议您注释掉配置以使其进入工作状态,然后一次取消注释部分找出导致问题的配置。

于 2017-06-03T23:20:21.297 回答