Маршрутный параметр 'id' ожидается от маршрута без параметров в ASP MVC проекте в C# - PullRequest
1 голос
/ 24 апреля 2020

Я работаю над проектом MVC в Visual Studio 2019, используя C#.

Это мой собственный маршрут в RouteConfig.cs:

routes.MapRoute(
name: "Create Product",
url: "products/create",
defaults: new { controller = "Product", action = "Create"}
);

Это мой продукт .cs Модель:

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace PapaComps.Models
{
    public class Product
    {
        [Display(Name = "Product Name")]
        [Required(ErrorMessage = "Please enter a product name.")]
        [StringLength(50, MinimumLength = 2, ErrorMessage = "Product Name must be between 2 and 50 characters")]
        public string Name { get; set; }

        [Display(Name = "Item Code")]
        [Required(ErrorMessage = "Please enter an item code.")]
        [StringLength(50, MinimumLength = 2, ErrorMessage = "Item Code must be between 2 and 50 characters long.")]
        public string ItemCode { get; set; }

        [Display(Name = "Price")]
        [Required(ErrorMessage = "Please enter a price.")]
        [Range(0, 999999, ErrorMessage = "Price must be between 0 and 999999.")]
        public decimal Price { get; set; }

        [Display(Name = "Category")]
        [Required(ErrorMessage = "Please choose a product  category.")]
        public int Category { get; set; }

        [Display(Name = "Product Image")]
        [Required(ErrorMessage = "Please upload an image of the product.")]
        public string Image { get; set; }

        [ScaffoldColumn(false)]
        public DateTime CreatedAt { get; set; }

        [ScaffoldColumn(false)]
        public DateTime UpdatedAt { get; set; }

        public Product(string Name, string ItemCode, decimal Price, int Category, string Image, DateTime CreatedAt, DateTime UpdatedAt)
        {
            this.Name = Name;
            this.ItemCode = ItemCode;
            this.Price = Price;
            this.Category = Category;
            this.Image = Image;
            this.CreatedAt = CreatedAt;
            this.UpdatedAt = UpdatedAt;
        }

        public Product()
        {
        }
    }
}

Это мои запросы GET и POST в ProductController.cs:

    // GET: products/create
    [HttpGet]
    public ActionResult Create()
    {
        return View();
    }

    // POST: products/create
    [HttpPost]
    public ActionResult Create(Product product)
    {
        ViewBag.errorMessage = TempData["ErrorMessage"];

        SqlConnection con = new SqlConnection("Data Source=DESKTOP-9CV3KT9\\SQLEXPRESS;Initial Catalog=PapaComps;Integrated Security=True");
        string query = "INSERT INTO products VALUES(@Name, @ItemCode, @Price, @Category, @Image, @CreatedAt, @UpdatedAt)";
        SqlCommand command = new SqlCommand(query, con);

        command.Parameters.Add("@Name", System.Data.SqlDbType.VarChar);
        command.Parameters.Add("@ItemCode", System.Data.SqlDbType.VarChar);
        command.Parameters.Add("@Price", System.Data.SqlDbType.Decimal);
        command.Parameters.Add("@Category", System.Data.SqlDbType.Int);
        command.Parameters.Add("@Image", System.Data.SqlDbType.VarChar);
        command.Parameters.Add("@CreatedAt", System.Data.SqlDbType.DateTime);
        command.Parameters.Add("@UpdatedAt", System.Data.SqlDbType.DateTime);
        command.Parameters["@Name"].Value = product.Name;
        command.Parameters["@ItemCode"].Value = product.ItemCode;
        command.Parameters["@Price"].Value = product.Price;
        command.Parameters["@Category"].Value = product.Category;
        command.Parameters["@Image"].Value = product.Image;
        command.Parameters["@CreatedAt"].Value = product.CreatedAt;
        command.Parameters["@UpdatedAt"].Value = product.UpdatedAt;

        try
        {
            con.Open();
            command.ExecuteNonQuery();
            TempData["ConfirmationMessage"] = "Product successfully created.";
            con.Close();
            return RedirectToAction("Index");
        }
        catch
        {
            con.Close();
            TempData["ErrorMessage"] = "Error. Product was not created.";
            return View();
        }
    }

GET предназначен только для возврата формы, а POST предназначен для обработки отправка формы.

Это мой Create.cs html:

@model PapaComps.Models.Product

@{
    ViewBag.Title = "Create";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

<h2>Create</h2>
@if (ViewBag.errorMessage != null) {
    <div class="alert alert-danger" role="alert">
        @(ViewBag.errorMessage)
    </div>
}

@using (Html.BeginForm()) 
{
    @Html.AntiForgeryToken()

    <div class="form-horizontal">
        <h4>Product</h4>
        <hr />
        @Html.ValidationSummary(true, "", new { @class = "text-danger" })
        <div class="form-group">
            @Html.LabelFor(model => model.Name, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.Name, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.Name, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.ItemCode, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.ItemCode, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.ItemCode, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.Price, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.Price, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.Price, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.Category, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.Category, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.Category, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.Image, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.Image, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.Image, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <input type="submit" value="Create" class="btn btn-default" />
            </div>
        </div>
    </div>
}

<div>
    @Html.ActionLink("Back to List", "Index")
</div>

@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
}

Когда я go to / products / create, я получаю следующую ошибку:

Словарь параметров содержит пустую запись для параметра 'id' ненулевого типа 'System.Int32' для метода 'System.Web. Mvc .ActionResult Details (Int32)' в 'PapaComps.Controllers.ProductController'. Необязательный параметр должен быть ссылочным типом, обнуляемым типом или быть объявлен как необязательный параметр. Имя параметра: параметры

Я не понимаю, почему он ищет параметр id, поскольку он явно не требуется ни для маршрута, ни для функций контроллера.

Однако, если я использую маршрут по умолчанию :

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

и go to / Product / Create это показывает форму просто отлично. Буду признателен за любую помощь, которую я могу получить. Спасибо.

...