新足迹

 找回密码
 注册

精华好帖回顾

· 同舟共济三人行——丰盛温馨的圣诞晚餐 (2006-12-25) poloand · 解决经济危机的真正方法 (2008-12-2) kingsford
· to老实和尚 (2007-7-27) 思思妈妈 · 陕西长安农家臊子面 (2010-1-16) bluesummer
Advertisement
Advertisement
查看: 1828|回复: 26

Http request parameter的design pattern应用 [复制链接]

发表于 2011-5-5 10:47 |显示全部楼层
此文章由 hornsay 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 hornsay 所有!转贴必须注明作者、出处和本声明,并保持内容完整
最近在做asp.net, 我们这个aspx application必须take http request, request 其中第一个parameter的value 不同,相对应的背后的工作也不同,想请教一下大家一般是如何处理的?
持不同股见者...
Advertisement
Advertisement

发表于 2011-5-5 11:44 |显示全部楼层
此文章由 典 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 典 所有!转贴必须注明作者、出处和本声明,并保持内容完整
Firstly, asp.net MVC for sure can meet your requirement ( actually I am not sure what's your requirement)

Here an old article can help you as welll http://www.mikesdotnetting.com/A ... ry-AJAX-and-ASP.NET

发表于 2011-5-5 12:06 |显示全部楼层

回复 典 2# 帖子

此文章由 hornsay 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 hornsay 所有!转贴必须注明作者、出处和本声明,并保持内容完整
Thanks.

假如有request是
1. abc.com.au/myapp.aspx?AppName=a&login=b&password=c
2. abc.com.au/myapp.aspx?AppName=b&postcode=2000&weight=2.00

就是说我的application 根据不同的AppName's value要做不同的parameter validation, e.g 如上面第一条,我必须保证login and password 有value

第二条中weight可能允许空的,或这个parameter可以不出现。

我想用composite pattern, 首先做一个basehttpparameterhandler, 然后建立不同的concrete class 来implement不同的request, 这个pattern 主要是用来做parameter的validation, 然后可能会pass 这个object到datamodule里。
持不同股见者...

发表于 2011-5-5 12:21 |显示全部楼层
此文章由 典 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 典 所有!转贴必须注明作者、出处和本声明,并保持内容完整
with MVC it's very easy to achive that.
Even with asp.net webform You can put a lot of if-else-else if you like.
Username-password shouldn't be in the URL.

评分

参与人数 1积分 +3 收起 理由
hornsay + 3 感谢分享

查看全部评分

发表于 2011-5-5 12:56 |显示全部楼层
此文章由 hornsay 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 hornsay 所有!转贴必须注明作者、出处和本声明,并保持内容完整
原帖由 于 2011-5-5 12:21 发表
with MVC it's very easy to achive that.
Even with asp.net webform You can put a lot of if-else-else if you like.
Username-password shouldn't be in the URL.


没仔细看MVC, 但感觉和UI有关。

我们是比较简单的take request and then return xml data.

现在有3个different requests, 我可以看到potential more requests in future development. 每一个request,它的第一个parameter which we name AppName, and AppName's value is different, 假如有10个different request, it will end up many if..else, and the code seems messy. I guess I need at least composit pattern and visitor pattern to handle this.
持不同股见者...

发表于 2011-5-5 20:35 |显示全部楼层
此文章由 hornsay 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 hornsay 所有!转贴必须注明作者、出处和本声明,并保持内容完整
今天做了一天,基本上搞出来一个比较简单的solution, 大约是这样.

{
  BaseHttpRequestHandler hHandler = getHttpHandler(Request.QueryString); //return concrete object
  if (hHandler != null)
    if (hHandler.ValidateParameters(Request.QueryString)
    {
       string xmldata = datamodule.getRequestXMLData(hHandler);
      Response.Write(xmldata);
    }
}
  class BaseHttpRequestHandler
  {
     public virtual bool ValidateParameters(NameValueCollection Collection)
    {
    }
  }

  然后只要有一个新的request, 就加一个concrete class, 这样在main 里面不需做任何改动。
持不同股见者...
Advertisement
Advertisement

发表于 2011-5-16 11:11 |显示全部楼层
此文章由 hornsay 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 hornsay 所有!转贴必须注明作者、出处和本声明,并保持内容完整
这几天在改进getHttpHandler

Current:

  function BaseHttpRequestHandler getHttpRequestHandler (string value)
{
    BaseHttpRequest hHandler = null;
   switch (value)
  {
  case "a":
     hHandler = new HttpRequestHandlerA();
    break;
  case "b":
    hHandler = new HttpRequestHandlerB();
    break;
  case "c":
   hHandler = new HttpRequestHandlerC();
   break;
default:
   break;
  }
  return hHandler;
}

觉得应该有更好的方法,类似于Type.GetType("System.DateTime"); 就是pass一个string, return一个object.
持不同股见者...

发表于 2011-5-16 12:36 |显示全部楼层
此文章由 flyspirit 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 flyspirit 所有!转贴必须注明作者、出处和本声明,并保持内容完整
你这个仅仅是valudation不同还是后面的所有处理都不同?

发表于 2011-5-16 12:51 |显示全部楼层
此文章由 flyspirit 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 flyspirit 所有!转贴必须注明作者、出处和本声明,并保持内容完整
我的意思是, 如果只是validation和返回的数据不同, 那只要在同一个page里面生成不同的class来处理就可以了,何必要生成不同的page?

发表于 2011-5-16 13:33 |显示全部楼层
此文章由 hornsay 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 hornsay 所有!转贴必须注明作者、出处和本声明,并保持内容完整
原帖由 flyspirit 于 2011-5-16 12:36 发表
你这个仅仅是valudation不同还是后面的所有处理都不同?


Valuation 和 后面的所有处理都不同.

Valuation这一块我已经做了.

这是其中的一个implementation:

  public class TFreightSingleHttpRequestHandler : TBaseHttpRequestHandler
  {
    public TFreightSingleHttpRequestHandler() : base()
    {
      this.PrimeName = "CarrServ";

      base.AddParameter("AppName", true);
      base.AddParameter("PaypartyCd", true);
     .....
      base.AddParameter("CommCd", false);
      base.AddParameter("CarrCode", true);
    }

    public override bool ValidateParameters(NameValueCollection Collection)
    {
      return base.ValidateParameters(Collection);
    }
  }


现在是这一块我觉得可以改进. 现在这样也可以,无非以后每增加一个request, 就加一个case. 不过想通过这个project学到在C#里更elegant的处理方法:

  public static HttpRequestHandler.TBaseHttpRequestHandler getHttpHandler(NameValueCollection Collection)
  {
    HttpRequestHandler.TBaseHttpRequestHandler hHandler = null;
    string s = Collection.Get("AppName");
    switch (s)
    {
      case "CarrServ":
      {
        hHandler = new HttpRequestHandler.TFreightSingleHttpRequestHandler();
        break;
      }
      case "All":
      {
        hHandler = new HttpRequestHandler.TFreightAllHttpRequestHandler();
        break;
      }
      case "Cheapest":
      {
        hHandler = new HttpRequestHandler.TFreightCheapestHttpRequestHandler();
        break;
      }
      default:
      {
        break;
      }
    }
    return hHandler;
  }
持不同股见者...

发表于 2011-5-16 13:49 |显示全部楼层
此文章由 hornsay 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 hornsay 所有!转贴必须注明作者、出处和本声明,并保持内容完整
原帖由 flyspirit 于 2011-5-16 12:51 发表
我的意思是, 如果只是validation和返回的数据不同, 那只要在同一个page里面生成不同的class来处理就可以了,何必要生成不同的page?


是在同一个page里产生不同的xml data. 下面就是在page load时的code, 来处理不同的request.

    protected void Page_Load(object sender, EventArgs e)
    {
      string webDef = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
      bool OKFlag = false;
      string ErrMsg = "";


      HttpRequestHandler.TBaseHttpRequestHandler Handler = TsmWebUtility.getHttpHandler(Request.QueryString);
      if (Handler != null)
      {
        OKFlag = Handler.ValidateParameters(Request.QueryString);
        if (!OKFlag)
        {
          Response.Write(webDef + smUtility.TUtility.AssignTagValue("Error", Handler.ErrMsg));
        }
        else
        {
          TdmConsignment dmConsignment = new TdmConsignment("FreightChargeEnquiry");
          string s = dmConsignment.getFreightEnquiryXMLData(Handler, ref ErrMsg);
          if (!String.IsNullOrEmpty(ErrMsg)) //error
          {
            Response.Write(webDef + smUtility.TUtility.AssignTagValue("Error", ErrMsg));
          }
          else
          {
            Response.C;
            Response.Write(webDef + "\n" + s);
          }
        }
      }
      else
      {
        Response.Write(webDef + smUtility.TUtility.AssignTagValue("Error", "Missing AppName"));
        OKFlag = false;
      }
  }

[ 本帖最后由 hornsay 于 2011-5-16 13:50 编辑 ]
持不同股见者...
Advertisement
Advertisement

2010年度奖章获得者

发表于 2011-5-16 13:54 |显示全部楼层
此文章由 dalaohu 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 dalaohu 所有!转贴必须注明作者、出处和本声明,并保持内容完整
你这个page load 厉害的, 该有的都有了。

发表于 2011-5-16 14:28 |显示全部楼层

回复 hornsay 11# 帖子

此文章由 flyspirit 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 flyspirit 所有!转贴必须注明作者、出处和本声明,并保持内容完整
那看不出有什么需要生成这么多concrete pages. 用validator class就可以了。

interface IParamValidator
{
  public validate()
}

class validator1 : IParamValidator
class validator2: IParamValidator

然后用一个用class factory根据第一个参数产生validator object

在page里面:
IValidator validator = validatorFactory.Create(queryString);
OKFlag = validator.Validate(Request.QueryString);

不过如果validater简单, 就不需要用pattern了。 直接把case语句和validate封装到一个类里就可以了。

评分

参与人数 1积分 +3 收起 理由
hornsay + 3 谢谢奉献

查看全部评分

发表于 2011-5-16 14:42 |显示全部楼层

回复 flyspirit 13# 帖子

此文章由 hornsay 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 hornsay 所有!转贴必须注明作者、出处和本声明,并保持内容完整
IValidator validator = validatorFactory.Create(queryString);
这个 return回来的应该是concrete object, 可能是validator1, 也可能是validate2, 想请教一下具体如何实现?

发表于 2011-5-16 14:44 |显示全部楼层
此文章由 hornsay 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 hornsay 所有!转贴必须注明作者、出处和本声明,并保持内容完整
原帖由 dalaohu 于 2011-5-16 13:54 发表
你这个page load 厉害的, 该有的都有了。


呵呵,怕讲不清楚.
持不同股见者...

发表于 2011-5-16 14:50 |显示全部楼层
此文章由 flyspirit 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 flyspirit 所有!转贴必须注明作者、出处和本声明,并保持内容完整
原帖由 hornsay 于 2011-5-16 14:42 发表
IValidator validator = validatorFactory.Create(queryString);
这个 return回来的应该是concrete object, 可能是validator1, 也可能是validate2, 想请教一下具体如何实现?


case语句, 这个逃不掉的, 除非你用dictionary查key, 但没有必要了。

class factory
{
  public IValidator Create(string query)
  {
    switch(firstParam)
      case 'a':
         return new ConcreteValidator_A;
         break;
      case 'b':
         return new ConcreteValidator_B;
         break;
   .....

  }
}
Advertisement
Advertisement

发表于 2011-5-16 14:51 |显示全部楼层
此文章由 cdfei 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 cdfei 所有!转贴必须注明作者、出处和本声明,并保持内容完整
需要这样吗?

发表于 2011-5-16 14:57 |显示全部楼层

回复 cdfei 17# 帖子

此文章由 flyspirit 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 flyspirit 所有!转贴必须注明作者、出处和本声明,并保持内容完整
要看人家的业务需求了。

发表于 2011-5-16 15:12 |显示全部楼层

回复 flyspirit 16# 帖子

此文章由 hornsay 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 hornsay 所有!转贴必须注明作者、出处和本声明,并保持内容完整
这个我已经实现了,用switch case根据不同的参数产生不同的object, 有没有比这个更elegant的?

我是想做一个list, 大概像这样:
  IList<string, string>
{
"a", "ValidatorA"
"b", "ValidatorB"
..
"n", "ValidatorN"
}
每一个object 有相对应的id(or 在这里是parameter的一个value), 这个id决定了产生哪一个object instance.

这样如果以后有新的request, 我在创建一个class后, 只要加一条line就可以了.
持不同股见者...

发表于 2011-5-16 15:25 |显示全部楼层
此文章由 飞翔翼 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 飞翔翼 所有!转贴必须注明作者、出处和本声明,并保持内容完整
说白了就是如何建立这个对应关系列表
1. 建立一个对应关系对象,如你所写的IList;
2. 写一个外部配置文件,初始化是读入;
3. IoC的模式,在每个class中加入annotation,应用启动后自动扫描复合条件的class,读取annotation后建立映射表。

3最麻烦,也最elegant,只需要维护单独的class,不知到.net里能不能做。

评分

参与人数 1积分 +2 收起 理由
hornsay + 2 感谢分享

查看全部评分

发表于 2011-5-16 15:34 |显示全部楼层
此文章由 flyspirit 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 flyspirit 所有!转贴必须注明作者、出处和本声明,并保持内容完整
原帖由 hornsay 于 2011-5-16 15:12 发表
这个我已经实现了,用switch case根据不同的参数产生不同的object, 有没有比这个更elegant的?

我是想做一个list, 大概像这样:
  IList
{
"a", "ValidatorA"
"b", "ValidatorB"
..
"n", "ValidatorN"
}
每一个object  ...


那要在数据库里面建立对应关系, 数据库表结构可以如下:

firstparam, class, assembly


在app里面load这张表, 然后根据firstParam, 用reflection动态装载assembly和class. 这样的耦合度最低。 而且你的validator class可以分散在不同的assembly里面, 需要新的class只要写新的assembly便可。

评分

参与人数 1积分 +3 收起 理由
hornsay + 3 感谢分享

查看全部评分

Advertisement
Advertisement

发表于 2011-5-16 15:40 |显示全部楼层
此文章由 梦呓人 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 梦呓人 所有!转贴必须注明作者、出处和本声明,并保持内容完整
原帖由 hornsay 于 2011-5-16 11:11 发表
这几天在改进getHttpHandler

Current:

  function BaseHttpRequestHandler getHttpRequestHandler (string value)
{
    BaseHttpRequest hHandler = null;
   switch (value)
  {
  case "a":
     hHandler = new HttpRequestHandlerA();
    break;
  case "b":
    hHandler = new HttpRequestHandlerB();
    break;
  case "c":
   hHandler = new HttpRequestHandlerC();
   break;
default:
   break;
  }
  return hHandler;
}

觉得应该有更好的方法,类似于Type.GetType("System.DateTime"); 就是pass一个string, return一个object.





如果每一种request你都可以建Handler Class的话,那你这么写:

function BaseHttpRequestHandler getHttpRequestHandler (string value)
{
  BaseHttpRequest hHandler = (BaseHttpRequest)Activator.CreateInstance(value + "RequestHandler"); // the whole string are names of your handler classes

  return hHandler;
}


这样你这个base都不需要动了,以后新type of app进来,只要多添加一个handler class就可以了

评分

参与人数 3积分 +13 收起 理由
hornsay + 5 感谢分享
flyspirit + 3 谢谢奉献
乱码 + 5 替你加了

查看全部评分

发表于 2011-5-16 15:46 |显示全部楼层

回复 BJ-KING 22# 帖子

此文章由 hornsay 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 hornsay 所有!转贴必须注明作者、出处和本声明,并保持内容完整
谢谢. 先白条,有分一定补上.

发表于 2011-5-16 16:29 |显示全部楼层
此文章由 梦呓人 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 梦呓人 所有!转贴必须注明作者、出处和本声明,并保持内容完整
原帖由 hornsay 于 2011-5-16 15:46 发表
谢谢. 先白条,有分一定补上.




谢谢了兄弟,记得如果系统还原到让你还只能+1、2分的时候千万等等,不着急的。等能加满的时候再加好了

发表于 2011-5-16 18:15 |显示全部楼层
此文章由 flyspirit 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 flyspirit 所有!转贴必须注明作者、出处和本声明,并保持内容完整
他给了我不少分, 给你来点

发表于 2011-5-17 13:09 |显示全部楼层
此文章由 hornsay 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 hornsay 所有!转贴必须注明作者、出处和本声明,并保持内容完整
原帖由 BJ-KING 于 2011-5-16 16:29 发表

谢谢了兄弟,记得如果系统还原到让你还只能+1、2分的时候千万等等,不着急的。等能加满的时候再加好了


兄弟牛人。

分分已加。
持不同股见者...
Advertisement
Advertisement

发表于 2011-5-17 13:16 |显示全部楼层
此文章由 hornsay 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 hornsay 所有!转贴必须注明作者、出处和本声明,并保持内容完整
原帖由 cdfei 于 2011-5-16 14:51 发表
需要这样吗?


这是我第一次在.NET里尝试,老板给了足够的时间,那就学的精一点。你可以做的很简单,但是一个学不到东西,另外我有大量的delphi projects未来要转到C#,  所以这些技术是不可少的。举个简单的例子,在delphi 里我有大量的EDI code, 未来都会用到Activator.CreateInstance.
持不同股见者...

发表回复

您需要登录后才可以回帖 登录 | 注册

本版积分规则

Advertisement
Advertisement
返回顶部