繁体   English   中英

如何修复 View 返回空白页? (HTTP 状态代码 405 - 方法不允许)

[英]How to fix View returning a blank page? (HTTP Status Code 405 - Method Not Allowed)

我有一个索引页面,允许用户查看股票列表。 用户可以通过单击“添加到关注列表”按钮将股票添加到他们的关注列表。 这会导致关注列表页面,发送用户 ID 和他们想要添加到他们的关注列表中的股票,以便他们的关注列表可以在他们登录到他们的帐户时随时保留。

我需要将方法设为 HTTPPost,因为我不希望用户 ID 作为查询字符串的一部分,因为这是敏感信息。 Watchlist 操作方法用于将股票信息和用户 ID 作为记录插入 Watchlist 表中,并显示用户的监视列表供他们查看。

这就是问题所在。我不断收到 HTTP 405 Method Not Allowed 错误。 我检查了代码中的语法,一切似乎都很好。 我觉得这可能与传递两个值(股票代码和用户 ID)而不是一个有关。

我将按照操作顺序显示相关代码。

索引.cshtml

@using Microsoft.AspNetCore.Identity
@model StockView.Models.StockExchangeViewModel
@inject UserManager<GenericUser> UserManager

@{
    ViewData["Title"] = "Index";
    var user = await UserManager.GetUserAsync(User);
    var userID = await UserManager.GetUserIdAsync(user);
    string UserId = (string)userID;
}

<h1>Stocks</h1>

<p>
    <a asp-action="Create">Create New</a>
</p>

<form asp-controller="Stocks" asp-action="Index" method="get">
    <p>

        <select asp-for="StockExchange" asp-items="Model.Exchanges">
            <option value="">All</option>
        </select>

        Title: <input type="text" name="SearchString" />
        <input type="submit" value="Filter" />
    </p>
</form>
<table class="table">
    <thead>
        <tr>
            <th>
                @Html.DisplayNameFor(model => model.Stocks[0].Ticker)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Stocks[0].Price)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Stocks[0].Volume)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Stocks[0].MarketCap)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Stocks[0].Exchange)
            </th>
        </tr>
    </thead>
    <tbody>
        @foreach (var item in Model.Stocks)
        {
            <tr>
                <td>
                    @Html.DisplayFor(modelItem => item.Ticker)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.Price)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.Volume)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.MarketCap)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.Exchange)
                </td>
            <td>
                <a asp-action="Edit" asp-route-id="@item.Ticker">Edit</a> |
                <a asp-action="Details" asp-route-id="@item.Ticker">Details</a> |
                <a asp-action="Delete" asp-route-id="@item.Ticker">Delete</a> |
                <a href="@Url.Action("Watchlist", "Stocks", new { stockTicker = item.Ticker, userId = UserId})">Add To Watchlist</a>
                <a href="@Url.Action("Chart", "Stocks", new {stockTicker = item.Ticker})">View Chart</a>
                
            </td>
            </tr>
        }
    </tbody>
</table>

StocksController.cs

 //This method is meant to post into a Watchlist object which is persisted by the database
        
        [HttpPost]
        public async Task<IActionResult> Watchlist(string stockTicker, string userId)
        {
            try
            {

                var stock = from s in _context.Stocks
                            where s.Ticker == stockTicker
                            select new { s.Ticker, s.Price, s.Exchange };
                Stocks tempStock = (Stocks)stock;

             
                //Insert into watchlist using stock attributes: UserId, Ticker, Price, Exchange


                await _context.Watchlists.AddAsync(new Watchlist
                {
                    GenericUserId = userId,
                    Ticker = tempStock.Ticker,
                    Price = tempStock.Price,
                    Exchange = tempStock.Exchange
                });
                _context.SaveChanges();

                var stocks = from s in _context.Watchlists
                             where s.GenericUserId == userId
                             select new { s.Ticker, s.Price, s.Exchange };


                ViewBag.stocks = stocks;
                return View();
            }
            catch (Exception ex)
            {
                return View("Error",
            new ErrorViewModel
            {
                RequestId = ex.ToString(),
                Description = "Error." + ex.Message
            });
            }
        }

我已经尝试更改 HTTP 属性,但我怀疑这是问题的根源,我还尝试查看操作方法是否执行任何逻辑,不幸的是,此时没有任何内容被保存到数据库中。

一切似乎都有道理,我不确定我可能会遗漏什么。

我还可以提供任何可能描绘更清晰画面的额外代码。

只需将表单元素的method属性值更改为post

<form asp-controller="Stocks" asp-action="Index" method="post"> 

Anchor Tag 只能发送HttpGet请求,而您的Watchlist操作只能接收 HttpPost 请求,这就是您获得HTTP Status Code 405 - Method Not Allowed的原因。

您只需删除[HttpPost]属性即可让Watchlist操作接收 Http Get 请求。 因为你的锚标签会生成 url 就像xxx/Stocks/Watchlist?stockTicker=xxxx&userId=xxxx ,如果Watchlist是 Http Get 方法,它的参数将绑定查询字符串中的值。 但此方法可能不符合您的要求,因为它会在查询字符串中显示 userId。

另一种方法是发送 Http Post 请求以访问Watchlist操作。 因为Anchor Tag不能发送Post请求,你可以添加一些css样式让按钮看起来像一个Anchor Tag。

.inline {
    display: inline;
}

.link-button {
    background: none;
    border: none;
    color: blue;
    text-decoration: underline;
    cursor: pointer;
    font-size: 1em;
    font-family: serif;
}

    .link-button:focus {
        outline: none;
    }

    .link-button:active {
        color: red;
    }

在此处输入图像描述

然后将您的Add To Watchlist锚标记更改为:

<button type="button" id="Edit" value="item.Ticker" data-value="userId" class="link-button" onclick="Watchlist(this)">
        Add To Watchlist
</button>

然后写一个JavaScript代码发帖到ajax。

<script>
    function Watchlist(button) {
        var result1 = button.value;
        var result2 = button.getAttribute("data-value");
        var formdata = new FormData();
        formdata.append("stockTicker",result1);
        formdata.append("userId", result2);

        $.ajax({
            type: 'POST',
            url: '/Stocks/Watchlist',
            data: formdata,
            processData: false,
            contentType: false
        });

    }
</script>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM