[英]How to check if an entry exists in a separate SQL Server table, and change which function is linked depending on whether it exists or not
在我开始之前,我对编码还比较陌生,并且将在不久的将来开始我的第一个初级角色,所以我目前的技能水平非常基础。
我正在创建一个个人 C# ASP.NET MVC Web 应用程序来跟踪用户参加的音乐活动、在这些活动中播放的艺术家以及用户看到的艺术家。 这一切都是由用户从数据库 (SQL Server) 中所有事件的索引视图中手动添加事件完成的,如下图所示。
https://i.stack.imgur.com/HOUGG.png
控制器动作:
public ActionResult GetEvents()
{
return View(_trackerService.GetEvents());
}
视图的标记:
@model IEnumerable<Tracker.Data.tbl_events>
@{
ViewBag.Title = "GetEvents";
}
<h2>GetEvents</h2>
<p>
@Html.ActionLink("Create New", "CreateEvent")
</p>
<table class="table">
<tr><h2>Upcoming Events</h2>
<th>
@Html.DisplayNameFor(model => model.Event_ID)
</th><th>
@Html.DisplayNameFor(model => model.Event_Name)
</th>
<th>
@Html.DisplayNameFor(model => model.Event_Date)
</th>
<th>
@Html.DisplayNameFor(model => model.Event_Location)
</th>
</tr>
@foreach (var item in Model.Where( x => x.Event_Date >= System.DateTime.Now).OrderBy(x => x.Event_Date))
{
<tr>
<td>
@Html.DisplayFor(modelItem => item.Event_ID)
</td>
<td>
@Html.DisplayFor(modelItem => item.Event_Name)
</td>
<td>
@Convert.ToString(string.Format("{0:dd/MM/yyyy}", item.Event_Date)) @*Converts the DateTime data type that ASP.NET uses by default into a string with the format of Date Only (https://stackoverflow.com/a/34990313/12764653)*@
</td>
<td>
@Html.DisplayFor(modelItem => item.Event_Location)
</td>
<td>
@*@Html.ActionLink("Edit", "Edit", new { id = item.Event_ID }) | *@
@Html.ActionLink("Details", "GetEventDetails", new { Event_ID = item.Event_ID }) |
@Html.ActionLink("Lineup", "../Event/GetLineup", new { Event_ID = item.Event_ID, Event_Name = item.Event_Name }) |
@if ((System.Web.HttpContext.Current.User != null) && System.Web.HttpContext.Current.User.Identity.IsAuthenticated)
{@*Checks to see if there is a current user*@
@Html.ActionLink("Add to my Events", "../Event/AddToUser", new { User_ID = Convert.ToString(System.Web.HttpContext.Current.User.Identity.GetUserId()).GetHashCode(), Event_ID = item.Event_ID })}
@*@Html.ActionLink("Delete", "Delete", new { id = item.Event_ID })*@
</td>
</tr>
}
</table>
用户将事件添加到他们的个人资料后,它会在数据库中创建一个条目,其中包含以下字段(链接如下):
https://i.stack.imgur.com/YQqHT.png
“添加到我的事件”功能的控制器方法:
[AcceptVerbs(HttpVerbs.Get | HttpVerbs.Post)]
public ActionResult AddToUser(tbl_eventhistory _event)
{
try
{
_trackerService.AddToUser(_event);
return RedirectToAction("GetEvents");
}
catch
{
return View();
}
}
我知道按照目前的方式,这很可能必须在控制器或视图中完成,并且可以检查“tbl_eventhistory”以查看当前用户的 User_ID 和特定的 Event_ID 是否存在条目,但是我不确定如何实际执行此操作,因此将不胜感激任何帮助。
编辑:显示的表是“tbl_events”的索引视图。 当用户从此视图向其配置文件添加事件时,它会使用该特定事件的参数在名为“tbl_eventhistory”的不同表中创建一个条目,该事件通过 Event_ID(tbl_event 的 PK)上的外键关联。 当用户将事件添加到 tbl_eventhistory 时,我只想从该特定事件的视图中删除“添加到用户”链接。
您的 Razor 视图中已经有一个Delete
链接 - 这似乎已经足够了:
@Html.ActionLink("Delete", "../Event/DeleteEvent", new { id = item.Event_ID })
然后你的EventController
会看起来像下面这些行:
[AcceptVerbs(HttpVerbs.Get | HttpVerbs.Post)]
public ActionResult DeleteEvent(int id)
{
try
{
_trackerService.DeleteForUser(HttpContext.Current.User.Identity.GetUserId(), _event); // this is where you verify whether currently logged in user has access and delete their associated event.
//depending on your data access framework of choice you should aim to fire a query like so:
//DELETE FROM table WHERE User_Id = :user_id AND Event_Id = :id
//that would cover you for users deleing only items belonging to them
return RedirectToAction("GetEvents");
}
catch
{
return View();
}
}
现在指出您的 AddEvent 代码的两个安全问题:
@Html.ActionLink("Add to my Events", "../Event/AddToUser", new { User_ID = Convert.ToString(System.Web.HttpContext.Current.User.Identity.GetUserId()).GetHashCode(), Event_ID = item.Event_ID })}
GetHashCode()
不是您认为的那样:将其用作标识符是不安全的,因为很可能会在默认实现上发生冲突HttpContext
对象,因此您应该能够在服务器端获取该User_ID
并尝试在标题中回答您的问题:
如何检查一个条目是否存在于单独的 SQL Server 表中,
我认为您不需要它来删除事件 - 请参阅上面代码中的注释
并根据是否存在更改链接的功能
我不确定我是否得到了这部分。 我觉得在查看SQL JOIN上的其他 SO 问题后,您可能可以自己回答这两个问题。 否则,我(以及这里的社区)将需要有关您的实际用例和目标的更多详细信息
设法终于找到了解决方案。 如果术语不正确,请原谅我。
我已经有一个函数来返回特定用户事件的索引视图(下面的 DAO 类代码)
public IList<tbl_eventhistory> GetUserEvents(string User_ID)
{
IQueryable<tbl_eventhistory> _eventHistory;
_eventHistory = from tbl_eventhistory in _context.tbl_eventhistory where tbl_eventhistory.User_ID == User_ID select tbl_eventhistory;
return _eventHistory.ToList<tbl_eventhistory>();
}
考虑如何在具有不同绑定模型的视图中使用此数据,我考虑使用 ViewBag 并遇到了这个: “如何检查 ViewBag 中的列表是否包含字符串” 。 从这个答案中,我将我的“GetEvents”函数修改为以下内容:
public ActionResult GetEvents()
{
List<string> UsersEvents = new List<string>();
foreach (var item in _trackerService.GetUserEvents(User_ID))
{
UsersEvents.Add(item.Event_ID.ToString());
}
ViewBag.MyEvents = _trackerService.GetUserEvents(User_ID);
ViewBag.MyEvents = UsersEvents;
return View(_trackerService.GetEvents());
}
如果我的理解是正确的,这将创建一个 List,它通过调用 'GetUserEvents' 操作填充并循环遍历结果中的每个条目。 将此列表移动到 ViewBag 然后允许我修改“GetEvents”ActionLinks 以在现有语句中包含一个额外的 IF 语句,以检查用户是否已登录:
@if ((System.Web.HttpContext.Current.User != null) && System.Web.HttpContext.Current.User.Identity.IsAuthenticated)
if (((IList<string>)ViewBag.MyEvents).Contains(item.Event_ID.ToString())){
<p>TEST</p> }
else{
@Html.ActionLink("Add to my Events", "../Event/AddToUser", new { User_ID = Convert.ToString(System.Web.HttpContext.Current.User.Identity.GetUserId()).GetHashCode(), Event_ID = item.Event_ID })}
}
这导致在适当的情况下显示“测试”而不是“添加到用户”的链接(如下所示,最终事件不存在于“tbl_eventhistory”中):
http://icecream.me/b459c9d17854b081a0804692f67c3aa3
我知道这可能是最有效的方法,但我很高兴它在经过很长时间试图弄清楚之后现在可以工作了。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.