Alternatively asp.net ashx handler switch case summary


Asp.net development projects, typically using the general request handler (the ashx) sent from the front end of the processing, because a plurality of handler processes the request, it is usually added ajax request an action parameter of the action handler in accordance with this accordingly or return the corresponding data, where most people think to make a judgment with a switch ... case, I also used a Switch beginning, but gradually discovered, unlike the case of each code block, which can not be to provide an independent variable scope! Moreover, if the case is more the case, then the code looks more bloated difficult to maintain;
that switch ... case how to replace it, I thought of the following two options:

1, instead of the switch entrusted with the dictionary ... case;

First, declare a private static commissioned in dictionary handler, key action as a string, value for the Func Principal; action, and then add to the dictionary corresponding to the method;
full sample code:

namespace WebApplication1
{

    public class Handler1 : IHttpHandler
    {
        static Dictionary<string, Action<HttpContext>> MapActions = new Dictionary<string, Action<HttpContext>>(StringComparer.OrdinalIgnoreCase)
        {
            {"Add", Add},
            {"Sub", Sub}
        };

        public void ProcessRequest(HttpContext context)
        {
            context.Response.ContentType = "text/plain";
            try
            {
                var action = context.Request["Action"];
                if (string.IsNullOrEmpty(action))
                {
                    context.Response.StatusCode = (int) HttpStatusCode.BadRequest;
                }

                if (MapActions.ContainsKey(action))
                {
                    var actionFun = MapActions[action];
                    if (actionFun != null)
                    {
                        actionFun(context);
                        //或
                        //actionFun.Invoke(context);
                    }
                    else
                    {
                        context.Response.StatusCode = (int) HttpStatusCode.NotImplemented;
                    }
                }
                else
                {
                    context.Response.StatusCode = (int) HttpStatusCode.NotFound;
                }
            }
            catch (Exception e)
            {
                context.Response.StatusCode = (int) HttpStatusCode.InternalServerError;
            }
            finally
            {
                context.Response.End();
            }
        }

        public static void Add(HttpContext context)
        {
            int num1 = int.Parse(context.Request["Num1"]);
            int num2 = int.Parse(context.Request["Num2"]);
            int result = num1 + num2;
            context.Response.Write(result);
        }

        public static void Sub(HttpContext context)
        {
            int num1 = int.Parse(context.Request["Num1"]);
            int num2 = int.Parse(context.Request["Num2"]);
            int result = num1 - num2;
            context.Response.Write(result);
        }

        public bool IsReusable
        {
            get
            {
                return false;
            }
        }
    }
}

2, an alternative using the reflection switch ... case;

Using the reflection, the action corresponding to the value of the specific method;
full sample code:

namespace WebApplication1
{

    public class Handler2 : IHttpHandler
    {
        static readonly Type[] SearchParamType = new[] { typeof(HttpContext) };
        public void ProcessRequest(HttpContext context)
        {
            var result = ActionInvoke(context);

            context.Response.ContentType = "text/plain";
            context.Response.Write(result);
        }
        private object ActionInvoke(HttpContext ctx)
        {
            var actionFun = this.GetType().GetMethod("ProcessAction_" + ctx.Request["action"] ?? "",
                BindingFlags.NonPublic |
                BindingFlags.IgnoreCase |
                BindingFlags.Instance |
                BindingFlags.Public,
                null,
                SearchParamType,
                null);
            if (null == actionFun)
            {
                return "UnknowAction";
            }
            return actionFun.Invoke(this, new[] { ctx });
        }
        public int ProcessAction_Add(HttpContext context)
        {
            int num1 = int.Parse(context.Request["Num1"]);
            int num2 = int.Parse(context.Request["Num2"]);
            int result = num1 + num2;
            return result;
        }

        public int ProcessAction_Sub(HttpContext context)
        {
            int num1 = int.Parse(context.Request["Num1"]);
            int num2 = int.Parse(context.Request["Num2"]);
            int result = num1 - num2;
            return result;
        }

        public bool IsReusable
        {
            get
            {
                return false;
            }
        }
    }
}

3, comparing the two schemes

Reflection will cause some performance loss; so using a delegate dictionary programs more reliable;

4, other programs

You can use design patterns to achieve, such as the factory model, state model, intermediary mode, but this is used in the above scenario, then there is the feeling of cracking a nut with a chopper;

5, description

In simple logic, case small branch, few extensions, you should use the switch statement, because simple and easy to read.
If the complex logic, complex and confusing case, but what is often extended, it should commission and reflection, using a caching mechanism.

6, reference

Reconstruction: switch mode or state policy statement into the mode: https://blog.csdn.net/qq_21381465/article/details/51298808
mediation patterns: https://www.cnblogs.com/insus/p/4134383.html


Guess you like

Origin www.cnblogs.com/willingtolove/p/11285680.html