2012-09-04 62 views
3

我知道有很多委託/函數的例子,但我找不到任何適用於我的例子,或者我只是不理解它們。需要在c中的標準try/catch函數中包裝函數#

我爲網站使用asp.net MVC,並且該網站需要一些外部應用程序與我的應用程序進行交互的Web服務調用。這些都需要一個函數來執行(去db和whatnot),並且每次都返回一個類似的數據模型。我想在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); 
} 

我希望能夠將特定功能以某種方式轉換爲變量傳遞到通用代碼。我查看了代表和匿名函數,但直到你自己做,它纔會令人困惑。

+3

你可以傳遞一個類型爲「Action」的對象給方法嗎?這可以讓你將真正的方法傳遞給'MillRequestCoil'等。不知道這是否可以在ASP.NET中工作。 – ChrisF

+0

@ChrisF,你能舉個例子嗎?我想這就是我想要做的,但不知道該怎麼做。 – Brandon

+0

現有答案顯示了我的建議。我對ASP.NET不熟悉,不知道我能建議的代碼是否可以工作。 – ChrisF

回答

5

把下面的某個地方進行訪問:

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); 
    }); 
} 
+0

我對代碼進行了編輯。我不會'只是創建一個對象,我會執行功能,而不是。 – Brandon

+0

你應該仍然可以做到這一點!例如。如果你可以在'MillRequestCoil'的主體中看到'dataRepository',你仍然可以在lambda函數中看到它('model => {...}')。 – Rawling

+0

謝謝。這是我正在尋找的。 – Brandon

1
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()); 
+0

這似乎相當複雜,只是爲了重新實現'Action <>'。 – Rawling

+1

超級回答。非常小的挑剔;會恭敬地建議界面名稱以「I」開頭,以表示界面術語,所以MillRequestCoil(等)的聲明將是實現界面的對象而不是更高級別對象的子類... –

+1

有一個最初的複雜程度,但是OP的問題表明需要重複使用多種情況,所以魯棒性對我來說似乎是贏家。只是我的$ 0.02 :) –

0

這是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模板代碼之間的關注很好分離模型建設的東西。