Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • Garrett Fisher 341 posts 496 karma points
    Feb 15, 2016 @ 16:49
    Garrett Fisher
    0

    "Magic" App_Code Folder and Codebehinds with Masterpages

    Hi,

    I am not a .NET developer by trade so please excuse any dumb questions or statements herein ;)

    I learned from a previous Umbraco project that the /App_Code folder is magical in the regard that it can be used for classes which one wishes to be compiled for use at runtime and it worked for me in one case to catch application-level errors and forward users to an error page.

    Now I find myself in a new situation but with a similar requirement. I'm implementing a 3rd party API whose goal is to inject HTML into my Umbraco page (on the back end) for SEO purposes since the normal display uses only javascript. This company provides a few DLLs and some simple sample code which I'm working with. I placed the furnished assemblies in the /bin directory, as instructed by their documentation. Aside from a log4net.dll version conflict error, which I worked around by adding a separate dependentAssembly reference in the web.config, adding the DLLs caused no problems. So then I created my *.cs ["BVSeo.aspx.cs"] file in /App_Code:

        using System;
        using System.Collections.Generic;
        using System.Linq;
        using System.Web;
        using System.Web.UI;
        using System.Web.UI.WebControls;
        using BVSeoSdkDotNet.Config;
        using BVSeoSdkDotNet.Content;
        using BVSeoSdkDotNet.Model;
        using BVSeoSdkDotNet.BVException;
    
        namespace MyNamespace
        {   
            public partial class SimpleRatingsAndReviews_Cloud : System.Web.UI.MasterPage
            {
                protected void Page_Load(object sender, EventArgs e)
                {
    
                     BVConfiguration bvConfig = new BVSdkConfiguration();
    
                     String cloudKey = Request.QueryString["cloudkey"];
                     String staging = Request.QueryString["staging"];
                     String testing = Request.QueryString["testing"];
                     String rootFolder = Request.QueryString["site"];
                     String productIdParam = Request.QueryString["productid"];
    
                     String subjectId = "5000001";
    
                     if (cloudKey != null)
                         bvConfig.addProperty(BVClientConfig.CLOUD_KEY, cloudKey);
                     else
                         bvConfig.addProperty(BVClientConfig.CLOUD_KEY, "blahblahblah");
                     if (staging != null)
                         bvConfig.addProperty(BVClientConfig.STAGING, staging);
                     else
                         bvConfig.addProperty(BVClientConfig.STAGING, "true");
                     if (testing != null)
                         bvConfig.addProperty(BVClientConfig.TESTING, testing);
                     else
                         bvConfig.addProperty(BVClientConfig.TESTING, "false");
    
                     if (rootFolder != null)
                         bvConfig.addProperty(BVClientConfig.BV_ROOT_FOLDER, rootFolder);
                     else
                         bvConfig.addProperty(BVClientConfig.BV_ROOT_FOLDER, "blahblahblah-Main_Site-en_US");
    
                     if (productIdParam != null)
                     {
                         //if productIdParameter is null then use the default value.  If it's not null then use the parameter.  If category
                         subjectId = productIdParam;
                     }
                     else
                         subjectId = "blahblahblah-1234567";
    
                     bvConfig.addProperty(BVClientConfig.SEO_SDK_ENABLED, "true");  // use this as a kill switch
                     bvConfig.addProperty(BVClientConfig.LOAD_SEO_FILES_LOCALLY, "false"); // set to false if using cloud-based content
                     bvConfig.addProperty(BVClientConfig.LOCAL_SEO_FILE_ROOT, "/");
    
                     bvConfig.addProperty(BVClientConfig.CRAWLER_AGENT_PATTERN, "yandex");
    
                     bvConfig.addProperty(BVClientConfig.EXECUTION_TIMEOUT, "1500");
                     bvConfig.addProperty(BVClientConfig.EXECUTION_TIMEOUT_BOT, "2000");
    
                     var bvParameters = new BVParameters
                     {
                         BaseURI =
                             Request.Url.ToString().Contains("?")
                                 ? Request.Url.ToString().Substring(0, Request.Url.ToString().IndexOf("?"))
                                 : Request.Url.ToString(),
                         PageURI = Request.Url.ToString(),
                         UserAgent = Request.UserAgent,
                         ContentType = new BVContentType(BVContentType.REVIEWS),
                         SubjectType = new BVSubjectType(BVSubjectType.PRODUCT),
                         SubjectId = subjectId
                     };
    
                     BVUIContent bvOutput = new BVManagedUIContent(bvConfig);
                     BVRRSummaryContainer.InnerHtml = bvOutput.getAggregateRating(bvParameters);
                     BVRRContainer.InnerHtml = bvOutput.getReviews(bvParameters);
                 }
            }   
      }
    

    Then in my Home.master template, I have the following CodeBehind and Inherits:

    <%@ Master Language="C#" MasterPageFile="~/masterpages/Master.master" CodeBehind="~/App_Code/BVSeo.aspx.cs" Inherits="MyNamespace.SimpleRatingsAndReviews_Cloud" AutoEventWireup="true" %>
    

    And in this masterpage these two HTML elements:

    <div class="bv">
    
         <div id="BVRRSummaryContainer" runat="server"></div>
    
         <div id="BVRRContainer" runat="server"></div>
    
    </div>
    

    This seems correct to me. No?? So here is where it gets interesting: this C# code all executes without error until the last two lines, where it references HTML DOM objects and attempts to populate them. The error is:

    The name 'BVRRSummaryContainer' does not exist in the current context.
    

    What am I doing wrong here? Is this not the way this is done? Is there some sort of race condition whereby the Class doesn't know what's in my page yet because it's not rendered? What do I need to change?

    I sincerely appreciate any guidance and counsel any Umbraco pros out there could offer. Re-creating the same idea in Visual Studio didn't yield any new directions or solutions.

    Thanks,

    Garrett

Please Sign in or register to post replies

Write your reply to:

Draft