未能路由到所需操作而未传递自定义段变量

时间:2014-05-21 20:07:28

标签: asp.net asp.net-mvc entity-framework-4 asp.net-mvc-routing

我有这两条路线。第二个将可选的自定义变量传递给action方法,并将其定向到名为DatedPosts的操作。

    routes.MapRoute(
        name: "Default",
        url: "{controller}/{action}/{id}",
        defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
    );


    routes.MapRoute(
    name: "GetDatePosts",
    url: "{controller}/{action}/{id}",
    defaults: new { controller = "Home", action = "DatedPosts",  id = UrlParameter.Optional}
    );

我的操作方法获取参数(如果已定义)并变为日期,然后它将获取博客中的所有帖子。也就是说,如果那个日期有任何我传递给视图的话。这种方法做我想做的事情:

        public ActionResult DatedPosts(string id)
        {
            //Post post = new Post();

            m_requestedDatedPosts = true;
            Session["RequestDatedPosts"] = m_requestedDatedPosts;

            string date = null;

            char oldChar = '/';
            char newChar = '-';
            if (!string.IsNullOrEmpty(id))
            {
                date = id.ToString();
            }

            //will hold the formated date
            string formatedDate = null;


            if (!string.IsNullOrEmpty(date))
            {
                //Convert dateString to shortDateString by replacing slashes with dashes
                formatedDate = date.Replace(oldChar, newChar);
            }
            else
            {
                ViewBag.CustomVariable = id == null ? "no posts with that date" : id;
                return RedirectToAction("Error", "Posts");
            }

            //put all posts in a list
            List<Post> m_posts = (from post in db.Posts select post).ToList();

            List<Post> m_datedPosts = new List<Post>();

            //var posts = (from post in db.Posts where post.CreatedDate == DateTime.Parse(formatedDate) select post).ToList();

            //Traverse the list of posts and get those with the given date
            foreach (var post in m_posts)
            {
                if (post.CreatedDate.ToShortDateString() == formatedDate)
                {
                    m_datedPosts.Add(post);
                }
            }

            //If there are no posts with that date redirect to Error action on post controller
            if (m_datedPosts.Count() == 0)
            {
                return RedirectToAction("Error", "Posts");
            }

            Session["DatedPostList"] = m_datedPosts.ToList();

            return RedirectToAction("Index", "Posts");
        }

This is my action View :

@{

    List<Post> posts;


    if (Session["RequestDatedPosts"] == null)
    {

        string requestDatedPostsStr = Session["RequestDatedPosts"].ToString();

        requestDatedPosts = Convert.ToBoolean(requestDatedPostsStr);

    }


    var datedPostList = (List<Post>)Session["DatedPostList"];

      if (requestDatedPosts)
    {

        posts = datedPostList;
    }

}

foreach (var post in posts)
{


    <div class="newsResult">

        <div class="title">@Html.DisplayFor(modelItem => post.Title)</div>

        <div class="updated"> <b>Created:</b> @Html.DisplayFor(modelItem => post.CreatedDate) </div>

        <div class="updated"> <b>Updated:</b> @Html.DisplayFor(modelItem => post.UpdateDate)</div>

        <div class="data"> <b></b>  @Html.DisplayFor(modelItem => post.Body)</div>

}

结果是路由工作,当且仅当我在事先定义路线中的日期时,如果只有这条路线:

    routes.MapRoute(
    name: "GetDatePosts",
    url: "{controller}/{action}/{id}",
    defaults: new { controller = "Home", action = "DatedPosts", id = "2014/05/21" }
    );
然而,这不是我想要的。在浏览器中,我想输入我选择的日期,如Localhost / DatedPosts / 2014/05/21 /,并在当天获取帖子(如果有的话)。

我得到的是HTTP错误404.0 - 未找到。另外,在测试时我发现了另一件我想避免的事情。事实证明,我的路由工作方式是我必须编写一个链接LocalHost / DatedPosts / DatedPosts /,以便至少被重定向到错误页面。同样,这不是我想要的,我想要一个这样的链接:Localhost / DatedPost / 2014/05/22并获得该日期的所有帖子。

有人可以帮忙吗?

提前谢谢!

1 个答案:

答案 0 :(得分:1)

您列出的路由基本相同,URL部分相同,因此路由引擎无法区分请求。

要了解您的情况,请尝试以下方法:

routes.MapRoute(
    name: "GetDatePosts",
    url: "DatedPost/{*id}",
    defaults: new { controller = "Home", action = "DatedPosts",  id = UrlParameter.Optional}
);

// default route should (generally) be last to ensure it doesn't catch any requests that may look similar 
routes.MapRoute(
    name: "Default",
    url: "{controller}/{action}/{id}",
    defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);