2016-04-28 11 views
1

私はでという名前のコントローラを開発していますし、最終的にそれがRouteAttributesを使用してMVCコントローラをどのように設計しますか?

だからhttp://myapp/at/5/step/6を意味するであろうプロジェクト番号ステップ数を必要とする利用プロジェクト= 5とステップ= 6

私はワン」

http://myapp/at

(DBで使用される最後のプロジェクトを探してみてください):のようなすべてのケースを処理するためのトンhttp://myapp/at/1(プロジェクト1のDBのステップを探してみてください)

以下の作品はありますが、これは必要以上に難しくしていますか?

public class ATController : Controller 
{ 
    [Route("at/{project:int}/step/{step:int}")] 
    public ActionResult Index(int project, int step) 
    { 
     var m = new ATViewModel(); 
     m.Project = project; 
     m.Step = step; 
     return View(m); 
    } 

    [Route("at/{project:int}")] 
    public ActionResult ProjectSuppliedNoStep(int project) 
    { 
     var p = project; 
     var s = 33; //fake lookup 
     return RedirectToAction("Index", new { project = p, step = s }); 
    } 

    [Route("at")] 
    public ActionResult NoProjectNoStep() 
    { 
     var p = 7; //fake lookup 
     var s = 33; 
     return RedirectToAction("Index", new { project = p, step = s }); 
    } 
} 

これは単体テストではありません。 ProjectSuppliedNoStepおよびNoProjectNoStepは常にnullを返します。 RedirectToActionが呼び出されたからだと思います。

答えて

0

Route属性を複数持つことができます。おそらく、これを組み合わせてパラメータをオプションにすることができますか?

[Route("at/{project:int?}/step/{step:int?}")] 
[Route("at/{project:int?}")] 
[Route("at")] 
public ActionResult Index(int? project, int? step) 
{ 
    var m = new ATViewModel(); 

    if (project.HasValue) 
    { 
     m.Project = project.Value; 

     if (step.HasValue) 
     { 
      m.Step = step.Value; 
     } 
     else 
     { 
      m.Step = 33; //fake lookup; 
     } 
    } 
    else 
    { 
     m.Project = 7; //fake lookup; 
     m.Step = 33;  //fake lookup; 
    } 

    return View(m); 
} 
+0

は、私はそのアプローチと思ったが、追加/削除するルートが一つの方法でRoutePrefix以外のオープン/クローズの原則 – WhiskerBiscuit

0

あなたはそれをよりよく理解するためにAttribute Routing in ASP.NET MVC 5を読むことができます。以下のようになりますあなたのコントローラ上で参照

...ここ

[RoutePrefix("at")] 
public class ATController : Controller 
{ 
    //GET /at/5/step/6 
    [Route("{project:int}/step/{step:int}")] 
    public ActionResult Index(int project, int step) { 
     var m = new ATViewModel(); 
     m.Project = project; 
     m.Step = step; 
     return View(m); 
    } 

    //GET /at/1 
    [Route("{project:int}")] 
    public ActionResult ProjectSuppliedNoStep(int project) { 
     var p = project; 
     var s = 33; //fake lookup 
     return RedirectToAction("Index", new { project = p, step = s }); 
    } 

    //GET /at 
    [Route("")] 
    public ActionResult NoProjectNoStep() { 
     var p = 7; //fake lookup 
     var s = 33; 
     return RedirectToAction("Index", new { project = p, step = s }); 
    } 
} 

はまた、すべてのパス(GREEN)がテストされ、あなたのコントローラのためのいくつかのユニットテストです。

[TestClass] 
public class MvcControllerAttributeRouteTests : ControllerUnitTests { 
    [TestMethod] 
    public void Index_Should_Return_ViewResult_With_Model() { 
     //Arrange 
     int project = 5; 
     int step = 6; 
     var controller = new ATController(); 
     //Act 
     var actionResult = controller.Index(project, step); 
     var viewResult = actionResult as ViewResult; 
     //Assert 
     Assert.IsNotNull(viewResult); 
     Assert.IsNotNull(viewResult.Model); 
     Assert.IsInstanceOfType(viewResult.Model, typeof(ATViewModel)); 
     var viewModel = viewResult.Model as ATViewModel; 
     Assert.AreEqual(project, viewModel.Project); 
     Assert.AreEqual(step, viewModel.Step); 
    } 

    [TestMethod] 
    public void Project_Supplied_No_Step_Should_Redirect_To_Index() { 
     //Arrange 
     int project = 1; 
     var controller = new ATController(); 
     //Act 
     var actionResult = controller.ProjectSuppliedNoStep(project); 
     var result = actionResult as RedirectToRouteResult; 
     //Assert 
     Assert.IsNotNull(result); 
     Assert.AreEqual("Index", result.RouteValues["action"], "the redirection was to at.index action"); 
     Assert.AreEqual(project, result.RouteValues["project"]); 
    } 

    [TestMethod] 
    public void No_Porject_No_Step_Should_Redirect_To_Index() { 
     //Arrange 
     var controller = new ATController(); 
     //Act 
     var actionResult = controller.NoProjectNoStep(); 
     var result = actionResult as RedirectToRouteResult; 
     //Assert 
     Assert.IsNotNull(result); 
     Assert.AreEqual("Index", result.RouteValues["action"], "the redirection was to at.index action"); 
     CollectionAssert.Contains(result.RouteValues.Keys, "project"); 
     CollectionAssert.Contains(result.RouteValues.Keys, "step"); 
    } 
} 
+0

に違反するだろう、どのようにあなたのコントローラクラスは私よりも違うのですか? – WhiskerBiscuit

+0

あなたはすでに正しい道にいました。それ以外の変更はあまりありませんでした。あなたは他の答えも試すことができますが、私はその構造に精通していません。それが動作すれば便利ですが。 – Nkosi

+0

私はあなたのアプローチが好きです。あなたのユニットテストはうまくいくと思います。それは安堵です。 – WhiskerBiscuit

関連する問題