【问题标题】:Need to wrap functions in a standard try/catch function in c#需要将函数包装在 c# 中的标准 try/catch 函数中
【发布时间】:2012-09-04 14:07:46
【问题描述】:

我知道有很多委托/函数示例,但我找不到任何适合我的示例,或者我只是不理解它们。

我正在将 asp.net MVC 用于网站,并且该网站需要一些 Web 服务调用以使外部应用程序与我的应用程序交互。这些都需要一个函数来执行(去 db 等等),并且每次都返回一个相似的数据模型。我想将每个调用包装在 try/catch 中并填充模型。

这是每次调用都会发生的通用代码。

var model = new ResponseDataModel();
try
{
     //execute different code here
}
catch (Exception ex)
{
    model.Error = true;
    model.Message = ex.ToString();
}
return View(model); // will return JSON or XML depending on what the caller specifies

这是我正在使用的控制器方法/功能之一

public ActionResult MillRequestCoil()
{
    var model = new ResponseDataModel();
    try
    {
        /* edit */
        //specific code
        string coilId = "CC12345";

        //additional code
        model.Data = dataRepository.doSomethingToCoil(coilId);

        //replaced code
        //model.Data = new { Coil = coilId, M3 = "m3 message", M5 = "m5 message" };
        model.Message = string.Format("Coil {0} sent successfully", coilId);
    }
    catch (Exception ex)
    {
         model.Error = true;
         model.Message = ex.ToString();
    }
    return View(model);
}

我希望能够以某种方式将特定函数转换为变量以传递给通用代​​码。我已经查看了委托和匿名函数,但在您自己做之前,它非常令人困惑。

【问题讨论】:

  • 你能把Action 类型的对象传递给方法吗?这将允许您将您的真实方法传递给MillRequestCoil 等。但不确定这是否适用于 ASP.NET。
  • @ChrisF,你能举个例子吗?我想这就是我想做的,但不知道该怎么做。
  • 现有答案显示了我的建议。我对 ASP.NET 不够熟悉,不知道我建议的代码是否可行。

标签: c# asp.net delegates anonymous-function


【解决方案1】:

将以下内容放在可访问的地方:

public static ActionResult SafeViewFromModel(
    Action<ResponseDataModel> setUpModel)
{
    var model = new ResponseDataModel();
    try
    {
        setUpModel(model);
    }
    catch (Exception ex)
    {
        model.Error = true;
        model.Message = ex.ToString();
    }
    return View(model); 
}

然后这样称呼它:

public ActionResult MillRequestCoil()
{
    return MyHelperClass.SafeViewFromModel(model =>
    {
        string coilId = "CC12345";
        model.Data = new {
            Coil = coilId,
            M3 = "m3 message",
            M5 = "m5 message" };
        model.Message = string.Format("Coil {0} sent successfully", coilId);
    });
}

【讨论】:

  • 我对代码进行了编辑。我不会只是创建一个对象,我会执行函数等等。
  • 你应该仍然可以做到这一点!例如。如果您可以在MillRequestCoil 的主体中看到dataRepository,您仍然可以在 lambda 函数中看到它(model =&gt; { ... } 位)。
  • 谢谢。这就是我一直在寻找的。​​span>
【解决方案2】:
public interface IAction{
    public void doAction(ResponseDataModel model);
}

public class Action1 : IAction
{
    public void doAction(ResponseDataModel model)
    {
        string coilId = "CC12345";
        model.Data = new { Coil = coilId, M3 = "m3 message", M5 = "m5 message" };
        model.Message = string.Format("Coil {0} sent successfully", coilId);
    }
}

class Class1
{
    public ActionResult MillRequestCoil(IAction action)
    {
        var model = new ResponseDataModel();
        try
        {
            //specific code
            action.doAction(model);
        }
        catch (Exception ex)
        {
            model.Error = true;
            model.Message = ex.ToString();
        }
        return View(model);
    }
}

用途:

var result = MillRequestCoil(new Action1());

或执行其他代码

var result = MillRequestCoil(new ActionXY());

【讨论】:

  • 重新实现Action&lt;&gt;似乎相当复杂。
  • 超级答案。非常轻微的挑剔;会恭敬地建议接口名称以“I”开头以指示接口命名法,因此 MillRequestCoil(等)的声明将是实现接口的对象,而不是更高级别对象的子类...
  • 有一个初始级别的复杂性,但 OP 的问题表明需要在多种情况下重用,所以鲁棒性对我来说似乎是赢家。只是我的 0.02 美元 :)
  • 这个问题是我必须为每个我想使用的函数创建一个类。我有大约 20 个这样的函数,并希望将代码保持在最短。它确实有效。
【解决方案3】:

这是 Rawling 答案的变体,我认为它具有更好的可读性:

public ActionResult MillRequestCoil()
{
    var model = CreateResponseDataModel(RunSpecificCode);

    return View(model);
}

public ActionResult MillDoSomethingElse ()
{
    var model = CreateResponseDataModel(RunOtherCode);

    return View(model);
}

private ResponseDataModel CreateResponseDataModel(Action<ResponseDataModel> action)
{
    var model = new ResponseDataModel();
    try
    {
        action(model);
    }
    catch (Exception ex)
    {
        model.Error = true;
        model.Message = ex.ToString();
    }
    return model;
}

private void RunSpecificCode(ResponseDataModel model)
{
    /* edit */
    //specific code
    const string coilId = "CC12345";

    //additional code
    model.Data = _dataRepository.DoSomethingToCoil(coilId);

    //replaced code
    //model.Data = new { Coil = coilId, M3 = "m3 message", M5 = "m5 message" };
    model.Message = string.Format("Coil {0} sent successfully", coilId);
}

private void RunOtherCode(ResponseDataModel obj)
{
    // some other piece of code
}

没有 lambda,并且您的特定代码和模板代码之间的关注点很好地分离,用于 try/catch 和模型构建。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-11-02
    • 2014-09-17
    • 2017-02-15
    • 2018-08-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-25
    相关资源
    最近更新 更多