Retornar uma mensagem de erro se não resultes são encontrados na consulta LINQ para o modelo
-
21-12-2019 - |
Pergunta
Eu criei uma página de edição para atualização de dados e ele funciona muito bem se o ID correto é passado, mas, quando um erro de ID é passado eu recebo uma exceção de referência nula.Eu sei que isto é devido ao fato de a consulta LINQ não encontrar quaisquer dados válidos a partir de banco de dados, mas não tenho certeza de como lidar com isso, a menos que eu adicione um punhado de IF
declarações, a meu ver, para verificar null cada vez que eu de referência o modelo.Aqui está o código que tem atualmente para o controlador.
public ActionResult EditSection(Int16 id = -1)
{
Section section = db.Sections.Find(id);
SectionAddEditVM model = new SectionAddEditVM { Section = section };
if (section != null)
{
if (section.Type == "Collection")
{
RedirectToAction("Collection", new { id = id });
}
model.SelectedType = section.Type;
return View(model);
}
ModelState.AddModelError("Section ID", "Invalid Section ID");
return View(model);
}
Visão:
@model SectionAddEditVM
@{
ViewBag.Title = "Edit " + Model.Section.Title + " Information";
}
<h2>
Edit @Model.Section.Title Information
</h2>
@using (Html.BeginForm(null, null, FormMethod.Post, new { enctype = "multipart/form-data" }))
{
@Html.AntiForgeryToken();
@Html.ValidationSummary(false)
<p>
@Html.HiddenFor(m => m.Section.ID)
<label for="Title">Seciton Title:</label> @Html.EditorFor(m => m.Section.Title)
<br />
<label for="RouteName">Section Route:</label> @Html.EditorFor(m => m.Section.RouteName)
<br />
<label for="Type">Section Type:</label> @Html.DropDownListFor(m => m.Section.Type, new SelectList(Model.Type, "Value", "Text"))
<br />
@Html.HiddenFor(m => m.Section.LogoFileID)
<label for="LogoFile">Logo Image:</label> <input id="LogoFile" name="LogoFile" type="file" />
<br />
<label for="Synopsis">Synopsis:</label> @Html.EditorFor(m => m.Section.Synopsis)
<br />
<input type="submit" value="Edit Information" />
</p>
}
Solução 2
A solução foi adicionar um ELSE
cláusula e iniciar um novo, em branco, de modelo.
public ActionResult EditSection(Int16 id = -1)
{
Section section = db.Sections.Find(id);
if (section != null)
{
if (section.Type == "Collection")
{
RedirectToAction("Collection", new { id = id });
}
SectionAddEditVM model = new SectionAddEditVM { Section = section };
model.SelectedType = section.Type;
return View(model);
}
else
{
section = new Section();
SectionAddEditVM model = new SectionAddEditVM { Section = section };
ModelState.AddModelError("Section ID", "Invalid Section ID");
return View(model);
}
}
Outras dicas
No seu controlador, você já está verificando se section
é null
.Assim, no caso de null
basta voltar uma visão diferente, que diz:"Não encontrado" ou algo assim.Além disso (como sugerido por @Aron) você pode retornar 404
código de status com este ponto de vista, então controlador seria algo parecido com isto:
// find section based on ID
// ... actual code ...
if (section != null)
{
// process data and assign to model
return View(model);
}
else
{
Response.StatusCode = (int) System.Net.HttpStatusCode.NotFound;
return View("NoSectionFound");
}
Note que, ao retornar de uma perspectiva diferente, você não retornar a uma página diferente.URL ainda é o mesmo, uma vez que é baseado no controlador de não o ver.Pela renderização de uma visão diferente para você evitar ter de complicar o código em vista que normalmente exibe os dados.
BTW, evite dar "muito" de informações como "Inválido seção de IDENTIFICAÇÃO", que pode direcionar o potencial invasor, onde a "picar" a próxima.
Eu também reorganizar o código para atribuir valor para model
somente quando a seção é encontrado e para o "não encontrado" ver, obviamente, você não precisa passar em qualquer modelo.