0

I asked a question "how to trigger 404 in controller", my post was closed and pointed me to an early question which was considered answered. I followed that link and tried to implement PageItem404: GetPageItemProcessor as described in the answer, I got compile error says

CS7036  There is no argument given that corresponds to the required formal parameter 'baseClient' of 'GetPageItemProcessor.GetPageItemProcessor(BaseClient)'

After I added the constructor like following

public PageItem404(BaseClient baseClient) : base(baseClient) { }

the pipeline throw exception after I added patch to configuration:

Server Error in '/' Application.

Could not create instance of type: Common.Feature.Errors.Pipelines.HttpRequest.PageItem404. No matching constructor was found. Constructor parameters:
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: Sitecore.Exceptions.ConfigurationException: Could not create instance of type: Common.Feature.Errors.Pipelines.HttpRequest.PageItem404. No matching constructor was found. Constructor parameters:

Source Error:


An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.
Stack Trace:

how to correctly implement GetPageItemProcessor and get it to work?

3
  • Is BaseClient available via dependency injection? Can you post your whole implementation of the class? Commented Mar 26 at 16:51
  • Also, when adding your patch file, did you add resolve="true" at the end? Commented Mar 26 at 16:57
  • Can you share the config patch through where you are adding PageItem404 processor. In case its a pipeline processor, then dependency will be resolved by adding resolve="true" in the config.
    – ckhanna
    Commented Mar 26 at 17:01

4 Answers 4

0

Based on the previous question, you are trying to redirect to 404 page inside the controller action. You can follow below steps to achieve the same.

Step1: Create the custom class extending ActionResult as below.

 public class TransferResult : ActionResult
 {
   public string Url { get; set; }
   public TransferResult(string url)
   {
        this.Url = url;
   }
   public override void ExecuteResult(ControllerContext context)
   {
        if (context == null)
            throw new ArgumentNullException("context");
        context.HttpContext.Server.TransferRequest(this.Url, false);
   }
  }

Step2: Inside the controller Action method you can return the custom ActionResult Type created above, depending on the condition when the video does not exist on the vimeo service.

public ActionResult Video()
    {
      var videoExist = false; //code to check if video exist
      if(!videoExist){
        return new TransferResult("{{url_for_404_page}}");
      }
      return View(""); 
    }
  

This will transfter the request to 404 page without the url being changed, inside the controller action.

Hope this helps!!!

2
  • Thanks very much! this looks very promising - but the company I am with they have several 404 page item stored, depends on the url, they are displaying different 404 item, the code looks like this in the 404 handler: var item404 = Get404Item(); Sitecore.Context.Item = item404; the Get404Item() function will look into the url pattern to retrieve few different sitecore 404 item defined. it is not a single /404 url instead it is the Sitecore.Context.Item was replaced.
    – John
    Commented Mar 27 at 15:06
  • you can use the same function var item404 = Get404Item(); to get 404 item. Therafter you can fetch the item url of 404 item and then use the above method to transfer the request to that item url.It will work as you desire.
    – ckhanna
    Commented Mar 27 at 15:33
0

I read your original question, I do not think you need another processor. Look for the item resolver in your code and if the video does not exist return null which should invoke 404.

Please note that this cannot be done in the controller, if you don't already have an item resolver you will need to create one and check if a video item exists based on the URL and process the request accordingly. Here is an example of item resolver https://gist.github.com/RyanABailey/d1b015bfde77051c353e1c013d8f0164

1
  • Thank you for your suggestion. In our controller code, we take the part of url as input, we use that information go after 3rd party video service, vimeo service, if we get null from that service, we know the video does not exists, that information cannot be handled with item resolver. in the controller, I need to return HttpNotfound() and be able to display not found item without changing the original url.
    – John
    Commented Mar 27 at 4:06
0

If you want to create a processor that inherits from , you need to do 2 things:

  1. First one (you've already done that) is creating a constructor with parameter
public class MyCustomProcessor: GetPageItemProcessor
{
    public MyCustomProcessor(BaseClient baseClient)
      : base(baseClient)
    {
    }
  1. Add resolve="true" in processor config
<processor 
    type="MyAssembly.MyNamespace.MyCustomProcessor, MyAssembly" 
    resolve="true"
    />

You were missing the resolve="true" and that's why Sitecore was not able to inject dependency for BaseClient parameter and tried to use parameterless constructor.

0

The Sitecore.Mvc.Pipelines.Response.GetPageItem.GetPageItemProcessor may not work due to constructor changes. Add resolve="true" on the patch and add a constructor to the pipeline. See the steps below:

This is the code of the new processor to handle 404.

using Sitecore;
using Sitecore.Abstractions;
using Sitecore.Diagnostics;
using Sitecore.Mvc.Pipelines.Response.GetPageItem;

namespace Yournamespace.Pipelines.GetPageItem
{
    public class Handle404 : GetPageItemProcessor
    {
        public Handle404(BaseClient baseClient)
            : base(baseClient)
        {
        }

        public override void Process(GetPageItemArgs args)
        {
            Assert.ArgumentNotNull(args, "args");

            var contextItem = GetContextItem();

            if (args.Result == null && contextItem != null)
            {
                args.Result = contextItem;
            }
        }
    }
}

A new processor needs to be added to mvc.getPageItem pipeline.

<?xml version="1.0" encoding="utf-8" ?>
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
    <sitecore>
        <pipelines>
            <mvc.getPageItem>
                <processor type="Yournamespace.Pipelines.GetPageItem.Handle404, YourDLL"
                           patch:before="processor[@type='Sitecore.Mvc.Pipelines.Response.GetPageItem.GetFromRouteValue, Sitecore.Mvc']"
                           resolve="true" />
            </mvc.getPageItem>
        </pipelines>
    </sitecore>
</configuration>

Hope this will solve your issue.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.