MVC-创建视图,使用从文本框传递搜索参数的存储过程从数据库中列出产品



我希望标题上的措辞不要混淆。。我试着尽可能具体。。。

目标

创建一个视图,允许客户使用SearchController上"索引视图"中的文本框搜索产品。当客户单击搜索按钮时,它将重定向到应该从文本框中获取字符串的搜索视图,将其用作我的存储过程的@param,然后将搜索视图作为列表(表)返回。

问题

我是MVC的新手,我可以在不使用存储过程的情况下获得一些自然的东西,但我正在进行的项目需要使用存储过程。

此外,当前搜索按钮未转到搜索视图()。

代码

我的搜索控制器:

using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Threading.Tasks;
using System.Net;
using System.Web;
using System.Web.Mvc;
using StoreFront.Models;
namespace StoreFront.Controllers
{
public class SearchController : Controller
{
private ProductContext Productdb = new ProductContext();
public ActionResult Index()
{
return View();
}
public ActionResult Search(string search)
{
return View(Productdb.Products.Where(x => x.ProductName.Contains(search) && x.IsPublished == true).ToList());
}
}
}

Index()视图:

@model IEnumerable<StoreFront.Models.Products>
@{
ViewBag.Title = "Search";
Layout = "~/Views/Shared/_CustomerLayout.cshtml";
}
<h2>@ViewBag.Title</h2>
<div class="panel">
<div class="panel-body">
@using (Html.BeginForm("Index", "Search", FormMethod.Get))
{
<div class="form-group">
<label>Input product to search for: </label>
@Html.TextBox("search")
</div>
<div class="form-group">
<input id="SearchButton" type="submit" class="btn btn-primary" value="Search" />
</div>
}
</div>
</div>

存储过程:

ALTER PROCEDURE [dbo].[spSearchProducts] 
@SearchText varchar(500)
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
SELECT ProductName,Price,ImageFile FROM Product WHERE ProductName = @SearchText AND IsPublished = 1
END

我创建了一个spSearchProductsModel.edmx,它包含存储过程,其函数名为GetProducts(),返回spSearchProductsModel_Result的复数

我已经被这个问题困扰了很长一段时间,我尝试浏览Youtube+早期堆栈问题的扩展。如有任何帮助,我们将不胜感激。

附言:如果你需要我发布更多代码,请告诉我。

您视图中的这一行:

@using (Html.BeginForm("Index", "Search", FormMethod.Get))

告知表单提交给CCD_ 4控制器的CCD_。因此,您的搜索操作永远不会受到影响。

相反,将其更改为:

@using (Html.BeginForm("Search", "Search", FormMethod.Get))

看看这对你来说是如何运作的。

调试提示:在控制器上的搜索操作中放置一个断点,您至少可以验证是否命中了正确的操作。如果没有,则表示您没有正确调用它,没有正确的动词,或者无法正确传递模型。(像Fiddler这样的工具对于帮助确定这些类型错误的原因是非常宝贵的)。

另一方面,我认为您的数据库调用不会按预期进行。调用存储过程与使用实体框架从表中读取略有不同(通常)。您正在执行通常的"从表中读取"方法,如果您想从表中进行读取(这是首选),则可以使用该方法。要调用存储过程,通常看起来是这样的:

return View(Productdb.Database.Query<ReturnObject>(
"ProcedureName", 
new System.Data.SqlClient.SqlParameter("@SearchText", search)
).ToList());

使用存储过程的一个棘手部分是,必须设置一个类型(在Query<ReturnObject>部分中显示为ReturnObject),以便精确映射到过程的返回列。通常,在您尝试时更容易使用本机表方法,因为EF通常会为您设置所有这些。(不过要谨慎一点,我通常不使用edmx的东西,所以我可能错了,但我几乎可以肯定你的代码是从表上读取的)

另一方面,请确保您有适当的视图。根据您的代码,您应该设置一个Search.cshtml视图,接受您传递给它的任何类型的IEnumerable<>。默认情况下,如果省略了视图名称,引擎将搜索与操作方法同名的视图。我更喜欢显式地传递视图名称和模型(为了可读性,模型通常在一个单独的变量中):

public ActionResult Search(string search) {
var model = Productdb.Database.Query<ReturnObject>(
"ProcedureName", 
new System.Data.SqlClient.SqlParameter("@SearchText", search)
).ToList();
return View("Search", model);
}

将操作方法更改为使用post属性。

[HttpPost]
public ActionResult Search(string search)
{
//Current code here
}

更换

@using (Html.BeginForm("Index", "Search", FormMethod.Get))

带有

@using (Html.BeginForm("Index", "Search"))

您现在应该可以进入搜索操作了。

最新更新