加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > asp.Net > 正文

asp.net-mvc – 使用View.Render方法将MVC视图转换为字符串的单

发布时间:2020-12-16 03:45:08 所属栏目:asp.Net 来源:网络整理
导读:我编写了将MVC视图转换为字符串和测试方法的方法,以检查它是否返回字符串. 当然它适用于Web,但是当我在NUnit中运行测试时,当方法试图调用View.Render时,它会在System.Web中抛出NullReferenceException. 这是StackTrace: w System.Web.VirtualPath.GetCacheK
我编写了将MVC视图转换为字符串和测试方法的方法,以检查它是否返回字符串.

当然它适用于Web,但是当我在NUnit中运行测试时,当方法试图调用View.Render时,它会在System.Web中抛出NullReferenceException.

这是StackTrace:

w System.Web.VirtualPath.GetCacheKey()
   w System.Web.Compilation.BuildManager.GetCacheKeyFromVirtualPath(VirtualPath virtualPath,Boolean& keyFromVPP)
   w System.Web.Compilation.BuildManager.GetVPathBuildResultFromCacheInternal(VirtualPath virtualPath,Boolean ensureIsUpToDate)
   w System.Web.Compilation.BuildManager.GetVPathBuildResultInternal(VirtualPath virtualPath,Boolean noBuild,Boolean allowCrossApp,Boolean allowBuildInPrecompile,Boolean throwIfNotFound,Boolean ensureIsUpToDate)
   w System.Web.Compilation.BuildManager.GetVPathBuildResultWithNoAssert(HttpContext context,VirtualPath virtualPath,Boolean ensureIsUpToDate)
   w System.Web.Compilation.BuildManager.GetVirtualPathObjectFactory(VirtualPath virtualPath,HttpContext context,Boolean throwIfNotFound)
   w System.Web.Compilation.BuildManager.GetObjectFactory(String virtualPath,Boolean throwIfNotFound)
   w System.Web.Mvc.BuildManagerWrapper.System.Web.Mvc.IBuildManager.FileExists(String virtualPath)
   w System.Web.Mvc.BuildManagerViewEngine.FileExists(ControllerContext controllerContext,String virtualPath)
   w System.Web.Mvc.VirtualPathProviderViewEngine.GetPathFromSpecificName(ControllerContext controllerContext,String name,String cacheKey,String[]& searchedLocations)
   w System.Web.Mvc.VirtualPathProviderViewEngine.GetPath(ControllerContext controllerContext,String[] locations,String[] areaLocations,String locationsPropertyName,String controllerName,String cacheKeyPrefix,Boolean useCache,String[]& searchedLocations)
   w System.Web.Mvc.VirtualPathProviderViewEngine.FindView(ControllerContext controllerContext,String viewName,String masterName,Boolean useCache)
   w System.Web.Mvc.ViewEngineCollection.<>c__DisplayClassc.<FindView>b__b(IViewEngine e)
   w System.Web.Mvc.ViewEngineCollection.Find(Func`2 lookup,Boolean trackSearchedPaths)
   w System.Web.Mvc.ViewEngineCollection.Find(Func`2 cacheLocator,Func`2 locator)
   w System.Web.Mvc.ViewEngineCollection.FindView(ControllerContext controllerContext,String masterName)
   w MvcApplication.Infrastructure.Services.MailingService.RenderEmailBody[T](String viewPath,T model,ControllerContext controllerContext,Boolean isParialView) w d:MyProjectsCertyfikatyNoblebranchesCertyfikaty3MvcApplicationInfrastructureServicesMailingService.cs:wiersz 175
   w MvcApplication.Tests.MailingServiceTests.ViewToStrngTest() w d:MyProjectsCertyfikatyNoblebranchesCertyfikaty3MvcApplication.TestsMailingServiceTests.cs:wiersz 144

渲染方法代码:

public string RenderEmailBody<T>(string viewPath,bool isParialView)
{
    ViewEngineResult viewEngineResult = null;
    if (isParialView == true)
    {
        viewEngineResult = ViewEngines.Engines.FindPartialView(controllerContext,viewPath);
    }
    else
    {
        viewEngineResult = ViewEngines.Engines.FindView(controllerContext,viewPath,null);
    }

    if (viewEngineResult == null)
    {
        throw new FileNotFoundException("Coukld not find view.");
    }

    var view = viewEngineResult.View;
    controllerContext.Controller.ViewData.Model = model;

    string result = null;

    using (var sw = new StringWriter())
    {
        var ctx = new ViewContext(controllerContext,view,controllerContext.Controller.ViewData,controllerContext.Controller.TempData,sw);
        view.Render(ctx,sw);
        result = sw.ToString();
    }

    return result;
}

并使用控制器上下文模拟测试方法:

Mock<HttpBrowserCapabilitiesBase> browserMock = new Mock<HttpBrowserCapabilitiesBase>();
browserMock.Setup(m => m.IsMobileDevice).Returns(false);

Mock<HttpServerUtilityBase> httpServerUtilityBaseMock = new Mock<HttpServerUtilityBase>(MockBehavior.Strict);

Mock<HttpResponseBase> httpResponseMock = new Mock<HttpResponseBase>(MockBehavior.Strict);
httpResponseMock.Setup(m => m.Cookies).Returns(new HttpCookieCollection() { new HttpCookie("ResponseCookieTest") });

Mock<HttpRequestBase> httpRequestMock = new Mock<HttpRequestBase>(MockBehavior.Strict);
httpRequestMock.Setup(m => m.UserHostAddress).Returns("127.0.0.1");
httpRequestMock.Setup(m => m.Cookies).Returns(new HttpCookieCollection() { new HttpCookie("RequestCookieTest") });
httpRequestMock.Setup(m => m.UserAgent).Returns("None");
httpRequestMock.Setup(m => m.Browser).Returns(browserMock.Object);
httpRequestMock.Setup(m => m.ApplicationPath).Returns("/");
httpRequestMock.Setup(m => m.AppRelativeCurrentExecutionFilePath).Returns("/");
httpRequestMock.Setup(m => m.PathInfo).Returns(string.Empty);
httpRequestMock.Setup(m => m.Form).Returns(new NameValueCollection());
httpRequestMock.Setup(m => m.QueryString).Returns(new NameValueCollection());

Mock<HttpSessionStateBase> httpSessionStateMock = new Mock<HttpSessionStateBase>(MockBehavior.Strict);
httpSessionStateMock.Setup(m => m.SessionID).Returns(Guid.NewGuid().ToString());

Mock<HttpContextBase> HttpContextMock = new Mock<HttpContextBase>(MockBehavior.Strict);
HttpContextMock.Setup(m => m.Request).Returns(httpRequestMock.Object);
HttpContextMock.Setup(m => m.Response).Returns(httpResponseMock.Object);
HttpContextMock.Setup(m => m.Server).Returns(httpServerUtilityBaseMock.Object);
HttpContextMock.Setup(m => m.Session).Returns(httpSessionStateMock.Object);

HttpContextMock.Setup(m => m.Items).Returns(new ListDictionary());

RouteData routeData = new RouteData();
routeData.Values.Add("controller","someController");
routeData.Values.Add("action","index");

Mock<ControllerContext> controllerContextMock = new Mock<ControllerContext>(MockBehavior.Strict);
controllerContextMock.Setup(m => m.HttpContext).Returns(HttpContextMock.Object);
controllerContextMock.Setup(m => m.RouteData).Returns(routeData);
controllerContextMock.Setup(m => m.Controller).Returns(new AccountController());

SiteConfigurationService siteConfigurationService = SiteConfigurationService.Instance();
siteConfigurationService.LoadConfig<SiteConfigurations>(this._siteConfigurationsRepository.GetDefaultConfig());

MailingService service = new MailingService(controllerContextMock.Object,siteConfigurationService);

string result = service.RenderEmailBody<object>("/ViewToRenderToString.cshtml",new object(),controllerContextMock.Object,false);

我读了HERE,原因是_virtualPath和HttpRuntime.AppDomainAppVirtualPathString int System.Web.VirtualPathString为NULL.

那么可以将它们设置为单元测试吗?

解决方法

您是否尝试过实施自己的VirtualPathProvider?

像这样的东西:

public class CustomVirtualPathProvider : VirtualPathProvider
    {
        internal class CustomVirtualFile : ViewVirtualFile
        {
            public override bool IsDirectory
            {
                get
                {
                    return base.IsDirectory;
                }
            }
            public override string Name
            {
                get
                {
                    return base.Name;
                }
            }
            public override string ResourceKey
            {
                get
                {
                    return base.ResourceKey;
                }
            }
            public override System.IO.Stream Open()
            {
                return base.Open();
            }
            public CustomVirtualFile(string path)
                : base(path)
            {

            }

        }
        public override bool FileExists(string virtualPath)
        {
            return base.FileExists(virtualPath);
        }
        public override VirtualFile GetFile(string virtualPath)
        {
            return base.GetFile(virtualPath);
        }
        public override VirtualDirectory GetDirectory(string virtualDir)
        {
            return base.GetDirectory(virtualDir);
        }
        public override bool DirectoryExists(string virtualDir)
        {
            return base.DirectoryExists(virtualDir);
        }


    }

然后在Global.asax中

///register our custom virtual path provider factory.
            HostingEnvironment.RegisterVirtualPathProvider(new CustomVirtualPathProvider());

使用此方法,您可以从任何位置呈现视图.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读