2017-01-23 1 views
2

이것은 컨트롤러 클래스입니다. 메소드 서명 만 보여주고 있습니다.Url.Action이 매개 변수 URL 대신 쿼리를 생성합니다.

[Authorize] 
[RoutePrefix("specification")] 
[Route("{action=index}")] 
public class SpecificationController : BaseController 
{ 
    [HttpGet] 
    [Route("~/specifications/{subcategoryID?}")] 
    public ActionResult Index(int? subcategoryID); 

    [HttpPost] 
    [Route("get/{subcategoryID?}")] 
    public JsonResult Get(int? subcategoryID); 

    [HttpGet] 
    [Route("~/specifications/reorder/{subcategoryID}")] 
    public ActionResult Reorder(int subcategoryID); 

    [HttpGet] 
    [Route("new/{id?}")] 
    public ActionResult New(int? id); 

    [HttpGet] 
    [Route("edit/{id?}")] 
    public ActionResult Edit(int id); 

    [HttpPost] 
    [ValidateAntiForgeryToken] 
    [Route("edit")] 
    public JsonResult Edit(SpecificationJson specification); 

    [HttpPost] 
    [Route("moveup")] 
    public JsonResult MoveUp(int specificationID); 

    [HttpPost] 
    [Route("movedown")] 
    public JsonResult MoveDown(int specificationID); 

    [HttpDelete] 
    [Route] 
    public ActionResult Delete(int id); 
} 

문제는 그 호출

@Url.Action("index", "specifications", new RouteValueDictionary() { { "subcategoryID", @subcategory.SubcategoryID } })

반환

/사양? subcategoryID = 15

대신

/사양/15

왜 이런 일이 무엇입니까? 나는이 경로에서 비슷한 방법을 기대하지 않는다!

답변

2

URL을 생성하는 귀하의 호출이 잘못되었습니다 . 컨트롤러 이름과 일치 시키려면 "사양"이 아닌 "사양"이어야합니다.

@Url.Action("index", "specification", new { subcategoryID=subcategory.SubcategoryID }) 

[Route] 속성에 지정된 URL은 외관상의 것입니다. 해당 라우트를 사용하여 URL을 생성하려면 라우트 값이 컨트롤러 이름 W 조치 메소드 이름과 일치해야합니다.

코드를 유지 보수하는 사람들 (코드가 약간 더 빠름)에 대해 더 명확하게하려면 컨트롤러 및 액션 이름과 마찬가지로 매개 변수 값을 파스칼 케이스로 만드는 것이 좋습니다.

@Url.Action("Index", "Specification", new { subcategoryID=subcategory.SubcategoryID }) 

왜 이런 일이 무엇입니까?

------------------------------------------------------------- 
| Route Key   | Route Value | Your Action Request | 
|--------------------|---------------|----------------------| 
| Controller   | Specification | Specifications  | No Match 
| Action    | Index   | Index    | Match 
| subcategoryID  | ?    | XXX     | Match (Always) 
------------------------------------------------------------- 

이 경로 일치를 얻으려면, @Url.Action의 모든 매개 변수는 경로 값 사전과 일치해야합니다. 문제는 실제 컨트롤러 이름SpecificationController이기 때문에 Controller=Specifications이 경로 값 사전에 정의되어 있지 않다는 것입니다. 따라서 경로 값의 이름은속성에 넣는 것과 관계없이 Specification입니다. ~/specifications/{subcategoryID?}은 들어오는 URL 만 일치시키고 URL이 생성 될 때 어떻게 보이는지를 결정합니다.

route 값에 Specification 대신 Specifications을 사용하려는 경우 작업 방법을 SpecificationsController이라는 새 컨트롤러로 이동해야합니다. 즉, 최종 사용자가 경로 값 이름을 볼 수 없기 때문에 어떤 차이가 있는지 알지 못합니다.

+0

당신이 말했듯이 내가 그렇게하면 그것이 효과가 있다는 것을 압니다. 그것은 이전과 같았습니다. 좀 더 일관성을 유지하기 위해 필자는 모든 결과가 표시된 뷰를 반환 할 때 나중에/specification이 아닌/spec을 지정해야한다고 결정 했으므로 이후의 설명은 단지 하나의 사양에 불과하다는 것을 의미합니다. 더 나아가, 나는 ~/specifications를 라우팅 속성에 사용함으로써 내가 라우트를 다시 시작하고 컨트롤러에 지정된 라우트 접두어를 사용하지 않는다는 것을 분명히했다. – Rob

+1

예, 작동하려면 작동 방식을 'SpecificationsController' 컨트롤러로 옮겨야합니다. 올바르게 지정하지 않으면 경로 미스가 발생하여 다른 경로와 일치하므로 검색어 문자열이 표시됩니다. – NightOwl888

+0

이것은 매력처럼 작동했습니다. 나는 경로를 다시 작성하는 것이 완전히 다시 작성 될 것이라고 생각했다. 당신 말이 맞아 보이는군요! – Rob

0

당신은 다음의 URL을 생성하기 위해이를 사용해야합니다 : /specifications/15

@Url.Action("index", "specifications", new { subcategoryID=subcategory.SubcategoryID }) 

[Route("~/specifications/{subcategoryID?}")] 
public ActionResult Index(int? subcategoryID); 

내가 잘못 했습니까 내가 매개 변수 이름으로 subcategoryID를 사용하는 방법을 되돌릴 수 있습니다 무엇?

당신은 다른 경로를 추가해야합니다 (는 기본 경로 전에) 다른 optional 매개 변수가하기 위해 :

뭔가 같은를 :

routes.MapRoute(
     "SecondRoute", 
     "{controller}/{action}/{subcategoryID}", 
      defaults: new { controller = "Home", action = "Index", subcategoryID = UrlParameter.Optional } 
); 
+0

왜'id'가 아닌'subcategoryID'입니까? –

+0

당신 말이 맞아요. 요점을 알려줘서 고마워. –

+0

이것이 작동하지 않습니다. – Rob