MVC两个Html.Action在一个视图中

时间:2016-02-01 22:23:12

标签: asp.net-mvc asp.net-mvc-4 azure

我正在使用MVC 5,我最近遇到了一个问题:

我有一个Controller [HomeController]和一个View with 2 Partial Partial1和Partial2。 我尝试使用Html.Action命令渲染两个部分(因为我希望调用相应的操作)。

所有动作都在HomeController中。

代码在本地主机和开发环境(Visual Studio 2015)上运行良好。 当我在Azure上发布项目时,我在尝试执行视图时遇到以下错误:

A single instance of controller 'HomeController' cannot be used to handle
multiple requests. If a custom controller factory is in use, make sure that
it creates a new instance of the controller for each request.  

我尝试使用[ChildActionOnly]并在" partial"上返回PartialViewResult。行动,但没有运气。

我知道我可以使用RenderPartial,但是,因为我想进行数据库调用以初始化Partials,所以我需要使用Html.Action。

关于这个问题的任何想法?

代码

public ActionResult ParentView()
{
    return View();
}

[ChildActionOnly]
public PartialViewResult _ChildView1()
{
   WebApi Client3 = new WebApi();

   Guid currentId = Guid.Empty;
   if (Session["CurrentId"] != null)
   {
        currentId = (Guid)Session["CurrentId"];
   }

   ResponseList retModel = Client3 .GetThingsFromDB(currentId);

   return PartialView("~/Views/Home/Folder/_View1.cshtml", retModel);
}

[ChildActionOnly]
public PartialViewResult _ChildView2()
{
   WebApi Client3 = new WebApi();

   Guid currentId = Guid.Empty;
   if (Session["CurrentId"] != null)
   {
        currentId = (Guid)Session["CurrentId"];
   }

   ResponseList retModel = Client3.GetThingsFromDB(currentId);

   return PartialView("~/Views/Home/Folder/_View2.cshtml", retModel);
}

查看

<div class="seperator">
@{
    Html.RenderAction("_ChildView1","Home");
}
</div>

<div class="seperator">
@{
    Html.RenderAction("_ChildView2","Home");                            
}
</div>

WebApi是使用IoC(StructureMap)的Rest WebApi(不同项目)的代理类,使用RestSharp调用WebApi。

我在Controller上添加了一个空构造函数。正如我所看到的,构造函数只被调用一次。不应该被叫3次吗? (一个用于父视图,一个用于两个RenderActions?)

启动 HomeController仅从Controller类派生(没有此控制器的基础)

using Microsoft.AspNet.Identity;
using Microsoft.Owin;
using Microsoft.Owin.Security.Cookies;
using Microsoft.Owin.Security.Facebook;
using Microsoft.Owin.Security.Google;
using Owin.Security.Providers.Instagram;
using Newtonsoft.Json.Linq;
using Owin;
using System;
using System.Net.Http;
using System.Security.Claims;
using System.Threading.Tasks;
using System.Web.Helpers;
using System.Configuration;

    [assembly: OwinStartup(typeof(Startup))]
    namespace WebPortal
    {
        public partial class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            ConfigureAuth(app);
        }

        public void ConfigureAuth(IAppBuilder app)
        {
            app.UseCookieAuthentication(new CookieAuthenticationOptions
            {
                AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
                LoginPath = new PathString("/Authorize/Login")
            });


            app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);

            var fbOptions = new FacebookAuthenticationOptions
            {
                Provider = new YoohBridgeFacebookAuthenticationProvider(),
                SignInAsAuthenticationType = DefaultAuthenticationTypes.ExternalCookie,
                AppId = ConfigurationManager.AppSettings["facebook.clientid"].ToString(),
                AppSecret = ConfigurationManager.AppSettings["facebook.clientsecret"].ToString(),
                BackchannelHttpHandler = new FacebookBackChannelHandler(),
                UserInformationEndpoint = "https://graph.facebook.com/v2.4/me?fields=id,name,email,first_name,last_name,location"
            };



            app.UseFacebookAuthentication(fbOptions);

            app.UseGoogleAuthentication(new GoogleOAuth2AuthenticationOptions()
            {
                ClientId = ConfigurationManager.AppSettings["google.clientid"].ToString(),
                ClientSecret = ConfigurationManager.AppSettings["google.clientsecret"].ToString()
            });



            AntiForgeryConfig.UniqueClaimTypeIdentifier = ClaimTypes.NameIdentifier;
        }
    }

    public class MyFacebookAuthenticationProvider : FacebookAuthenticationProvider
    {
        public MyFacebookAuthenticationProvider() : base() { }

        public override void ApplyRedirect(FacebookApplyRedirectContext context)
        {
            context.Response.Redirect(context.RedirectUri + "&display=popup");
        }
    }

    public class FacebookBackChannelHandler : HttpClientHandler
    {
        protected override async System.Threading.Tasks.Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, System.Threading.CancellationToken cancellationToken)
        {
            if (!request.RequestUri.AbsolutePath.Contains("/oauth"))
            {
                request.RequestUri = new Uri(request.RequestUri.AbsoluteUri.Replace("?access_token", "&access_token"));
            }

            return await base.SendAsync(request, cancellationToken);
        }
    }
}

完整追踪

at System.Web.WebPages.WebPageExecutingBase.NormalizeLayoutPagePath(String layoutPagePath)
   at System.Web.WebPages.WebPageBase.PopContext()
   at System.Web.WebPages.WebPageBase.ExecutePageHierarchy(WebPageContext pageContext, TextWriter writer, WebPageRenderingBase startPage)
   at System.Web.Mvc.RazorView.RenderView(ViewContext viewContext, TextWriter writer, Object instance)
   at System.Web.Mvc.BuildManagerCompiledView.Render(ViewContext viewContext, TextWriter writer)
   at System.Web.Mvc.ViewResultBase.ExecuteResult(ControllerContext context)
   at System.Web.Mvc.ControllerActionInvoker.InvokeActionResult(ControllerContext controllerContext, ActionResult actionResult)
   at System.Web.Mvc.Async.AsyncControllerActionInvoker.&lt;&gt;c__DisplayClass21.&lt;BeginInvokeAction&gt;b__1e(IAsyncResult asyncResult)
   at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult`1.CallEndDelegate(IAsyncResult asyncResult)
   at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResultBase`1.End()
   at System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeAction(IAsyncResult asyncResult)
   at System.Web.Mvc.Controller.&lt;BeginExecuteCore&gt;b__1d(IAsyncResult asyncResult, ExecuteCoreState innerState)
   at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult)
   at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResultBase`1.End()
   at System.Web.Mvc.Controller.EndExecuteCore(IAsyncResult asyncResult)
   at System.Web.Mvc.Controller.&lt;BeginExecute&gt;b__15(IAsyncResult asyncResult, Controller controller)
   at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult)
   at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResultBase`1.End()
   at System.Web.Mvc.Controller.EndExecute(IAsyncResult asyncResult)
   at System.Web.Mvc.Controller.System.Web.Mvc.Async.IAsyncController.EndExecute(IAsyncResult asyncResult)
   at System.Web.Mvc.MvcHandler.&lt;BeginProcessRequest&gt;b__5(IAsyncResult asyncResult, ProcessRequestState innerState)
   at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult)
   at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResultBase`1.End()
   at System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult)
   at System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result)
   at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
   at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean&amp; completedSynchronously)

2 个答案:

答案 0 :(得分:0)

我最好的猜测是您正在使用IoC(控制反转)模式,并使用IoC容器(Castle Windsor,Autofac,...)实例化您的控制器。真的吗?如果是,请确保控制器未注册为单身人士 - 或者他们的生命周期不是“每个网络请求”。新控制器应在每次需要时进行实例化,即其寿命应该是暂时的(在Castle Windsor的术语中)。

答案 1 :(得分:0)

经过漫长的研究和许多测试,一如既往,答案就像那样简单:

清洁 - &gt;重建(本地)

发布 - &gt;选中&#34;删除目的地的其他文件&#34; (在azure上清理项目应用程序)

非常感谢答案和efford!