ASP.Net MVC始终将0路由到该方法

时间:2018-11-27 16:28:16

标签: c# asp.net-core-mvc

这是我的观点(全视图)

@model List<BlogPostLayoutModel>
@{
ViewData["Title"] = "Index";
}

@foreach (var item in Model)
{
<div class="row">
    <div class="col-md-12">
        <h2 class="text-center">
            @item.Title
        </h2>
        <div class="col-md-9 thumbnail">
            <img src="/home/getimage/@item.IDPost" />
        </div>
        <p>@item.Content</p>
    </div>
</div>
}

这是Home控制器的GetImage方法

public async Task<ActionResult> GetImage(int id)
    {
        var post = await _blogContext.Posts.FirstOrDefaultAsync(m => m.IDPost == id);

        return File(post.Image, post.Image_Extension);
    }

当我调试时,我可以看到Model中的每个对象的ID都为〜1000(数据库中的某个实数),但是当我调试GetImage方法时,它始终会传递0。

路由定义:

app.UseMvc(routes =>
        {
            routes.MapRoute(
                name: "default",
                template: "{controller=Home}/{action=Index}/{pageNumber=1}");
        });

控制器方法:

public async Task<IActionResult> Index(int pageNumber)
    {
        blogPages = BlogPages();
        ViewBag.pageNumber = pageNumber;
        ViewBag.blogPages = blogPages;
        List<BlogPostLayoutModel> bPLMList = PostsForBlogPage(pageNumber);
        return View(bPLMList);
    }

和BlogPostLayourModel定义(没有不必要的方法):

public class BlogPostLayoutModel
{
    public int IDPost { get; set; }
    public string Title { get; set; }
    public string Content { get; set; }
    public string AuthorUserName { get; set; }
    public DateTime DateCreated { get; set; }
    public byte[] ImageFromPost { get; set; }
    public string Image_Extension { get; set; }
 }

2 个答案:

答案 0 :(得分:2)

因此您的路线说第三个路线参数称为pageNumber。现在考虑您的图片链接:

<img src="/home/getimage/@item.IDPost" />

在路由此请求时,帖子ID将映射到pageNumber。现在看一下动作声明:

public async Task<ActionResult> GetImage(int id)

这表示该操作期望一个请求具有一个名为id的参数。将请求路由到该操作后,将发生模型绑定,并且在此过程中,路由和请求参数将映射到操作的输入。在这种情况下,模型绑定器将无法找到操作所需的id,因为请求中没有该名称的请求。其中唯一的参数具有名称pageNumber。因此,它将使用默认值0初始化id

解决此问题的一种方法是使用查询字符串而不是route参数,并且这种方式将帖子ID明确命名为id:

<img src="/home/getimage?id=@item.IDPost" />

答案 1 :(得分:2)

实际上,在正常情况下,使用pageNumber作为默认参数不是一个明智的选择。

您应该将路由更改为:

app.UseMvc(routes =>
    {
        routes.MapRoute(
            name: "default",
            template: "{controller=Home}/{action=Index}/{id?}");
    });

这将破坏使用pageNumber作为默认路由的代码,但是您将获得一个可以正常工作的事实:

<img src="/home/getimage/@item.IDPost" />

对于其他链接,使用pageNumber时,您需要以下语法:

<img src="/home/getimage?pageNumber=@item.PageNumber" />

这一切的动机是由于以下事实:

  • 经常,您需要一个(详细)记录,并经常通过id查询
  • pageNumber通常带有pageSize,因此基本上是一个更复杂的对象。

此外,如果要将pageNumber设为单个操作的默认参数,则可以使用route属性对其进行标记:

[Route("{pageNumber}")]
public async Task<IActionResult> Index(int pageNumber)

有关路由的更多信息,请参见herehere(假设您使用的是asp.net Core。