从通用处理程序(.ashx)进行异步调用

问题描述 投票:9回答:2

我在我的网站上有一个表单,它将json发布到异步处理程序,它验证数据并返回响应OK或错误,我将根据我的处理程序给出的响应在客户端上进行重定向。

但是当响应正常时,我想异步执行一些任务。但异步调用在.ashx代码中不起作用。它始终是同步的。

你能否就此给我一个建议?

码:

public class ValidateHandler : IHttpHandler, IRequiresSessionState
    {

        public void ProcessRequest(HttpContext context)
        {
            NameValueCollection nvcForm = context.Request.Form;
            Dictionary<string, string> errorFieldsDict = new Dictionary<string, string>();


            foreach (string nameValueKey in nvcForm.AllKeys)
            {
                regExpToTest = string.Empty;
                switch (nameValueKey)
                {
                    case "firstName":
                      //validate
                        break;
                    case "lastName":
                       //validate
                        break;
                    case "email":
                        //validate
                        break;
                    case "phoneNumber":
                    //validate
                        break;
                    case "phoneCountryCode":
                        //validate
                        break;
                    case "country":
                     //validate
                        break;
                    case "addressLine1":
                        //validate
                        break;
                    case "addressLine2":
                       //validate
                        break;
                    case "city":
                        //validate
                        break;
                    case "postalCode":
                        //validate
                        break;
                    default:
                        //validate
                        break;
                }
                if (!string.IsNullOrEmpty(regExpToTest) && !Regex.IsMatch(nvcForm[nameValueKey], regExpToTest) && !string.IsNullOrEmpty(nvcForm[nameValueKey]))
                {
                    errorFieldsDict.Add(nameValueKey, "Please Enter Correct Value");
                    isSuccess = false;
                }
            }

            //Do your business logic here and finally

            if (isSuccess)
            {
                JavaScriptSerializer serializer = new JavaScriptSerializer();
                try
                {
                    Dictionary<string, object> formValues = GetDictionaryForJson(nvcForm);
                    string previoiusUrl = GetRequestedURL(context);
                    string partner = string.Empty;
                    if (System.Web.HttpContext.Current.Session["yourpartner"] != null)
                        partner = System.Web.HttpContext.Current.Session["yourpartner"].ToString();
                    else if (System.Web.HttpContext.Current.Request.QueryString["utm_source"] != null)
                        partner = System.Web.HttpContext.Current.Request.QueryString["utm_source"];
                    else
                        partner = "company";
                    formValues.Add("partnerCode", partner);
                    string brochureType = string.Empty;
                    if (!string.IsNullOrEmpty(nvcForm["addressLine1"]) || !string.IsNullOrEmpty(nvcForm["addressLine2"]))
                        brochureType = "FBRO";
                    else
                        brochureType = "EBRO";
                    //Create a row in database
                    Item programItem = Sitecore.Context.Database.Items.GetItem(programRootpath + nvcForm["selectYourProgram"]); ;
                    AsyncMailSender caller = new AsyncMailSender(SendEmail);
                    IAsyncResult result = caller.BeginInvoke(programItem, nvcForm["email"], null, null);
                }
                catch (Exception ex)
                {
                    isSuccess = false;
                    Log.Error("Enquiry handler failure: " + ex.Message, ex);
                    response.response = "error";
                    response.message = ex.Message;
                    context.Response.ContentType = "application/json";
                    context.Response.Write(JsonConvert.SerializeObject(response));
                }
                if (isSuccess)
                {
                    response.response = "ok";
                    context.Response.ContentType = "application/json";
                    context.Response.Write(JsonConvert.SerializeObject(response));
                }

            }
            else
            {
                response.response = "errorFields";
                response.errorFields = errorFieldsDict;
                context.Response.ContentType = "application/json";
                string responseJson = JsonConvert.SerializeObject(response);
                context.Response.Write(JsonConvert.SerializeObject(response, Newtonsoft.Json.Formatting.None));
            }

        }
        private string GetRequestedURL(HttpContext context)
        {
            string previousURL = string.Empty;
            try
            {
                previousURL = context.Request.ServerVariables["HTTP_REFERER"];
            }
            catch
            {
                previousURL = context.Request.Url.AbsolutePath;
            }
            return previousURL;
        }
        public bool IsReusable
        {
            get
            {
                return false;
            }
        }
        private void SendEmail(Item programItem, string toEmail)
        {

            if (programItem != null)
            {
               SendEmail()

            }
        }
        private Dictionary<string, object> GetDictionaryForJson(NameValueCollection formValues)
        {
            Dictionary<string, object> formDictionary = new Dictionary<string, object>();
            foreach (string key in formValues.AllKeys)
            {
                formDictionary.Add(key, formValues[key]);
            }

            return formDictionary;
        }

    }
    public delegate void AsyncMailSender(Item program, string toAddress);

PS:我确实隐藏了一些只是我们业务的代码。但是如果你能对此发表评论那就太棒了。

多谢你们

asp.net .net asynchronous delegates ashx
2个回答
8
投票

你需要使用IHttpAsyncHandler而不是IHttpHandler,并在web.config文件中注册它。浏览器还会观察连接限制,因此请确保正确配置IIS以处理多个连接,保持活动等。

这是一个详细的演练:http://msdn.microsoft.com/en-us/library/ms227433.aspx


19
投票

在ASP.NET 4.5中是HttpTaskAsyncHandler。你可以像这样使用它:

public class MyHandler : HttpTaskAsyncHandler {

    public override async Task ProcessRequestAsync(HttpContext context) {
       await WhateverAsync(context);
    }

}
© www.soinside.com 2019 - 2024. All rights reserved.