Итак, я хочу убедиться, что я делаю это правильно, поскольку у меня возникла странная проблема, которую я не могу понять.У меня есть веб-приложение ASP.NET для отслеживания проблем качества в производственной среде.После создания новой записи уведомление по электронной почте отправляется соответствующему персоналу.В этом письме я хочу включить ссылку, которая открывает конкретное представление для этой конкретной записи.
В письме у меня есть следующая гиперссылка:
var link = "<a href = "\"\\webapp-dev\\Nonconformance\\AP\\Details_APInt\\" + nonconform.ID + "\">Click here to view details</a>";
Контроллеры написаныв C #.Я использую SmtpClient
для отправки электронного письма с этой ссылкой в mail.Body
вместе с другой информацией.Когда я щелкаю URL в письме, я получаю NullReferenceException error: Object reference not set to an instance of an object
.
Line 3:
Line 4: @{
Line 5: ViewBag.Title = "Details_APInt"; <--- failing on this line
Line 6: }
Line 7:
Вот трассировка стека:
[NullReferenceException: Object reference not set to an instance of an object.]
ASP._Page_Views_ap_Details_APInt_cshtml.Execute() in C:\Nonconformance\Views\ap\Details_APInt.cshtml:5
System.Web.WebPages.WebPageBase.ExecutePageHierarchy() +251
System.Web.Mvc.WebViewPage.ExecutePageHierarchy() +147
System.Web.WebPages.StartPage.ExecutePageHierarchy() +87
System.Web.WebPages.WebPageBase.ExecutePageHierarchy(WebPageContext pageContext, TextWriter writer, WebPageRenderingBase startPage) +106
System.Web.Mvc.ViewResultBase.ExecuteResult(ControllerContext context) +374
System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilterRecursive(IList`1 filters, Int32 filterIndex, ResultExecutingContext preContext, ControllerContext controllerContext, ActionResult actionResult) +87
System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilterRecursive(IList`1 filters, Int32 filterIndex, ResultExecutingContext preContext, ControllerContext controllerContext, ActionResult actionResult) +831
System.Web.Mvc.ControllerActionInvoker.InvokeActionResultWithFilters(ControllerContext controllerContext, IList`1 filters, ActionResult actionResult) +81
System.Web.Mvc.Async.<>c__DisplayClass21.<BeginInvokeAction>b__1e(IAsyncResult asyncResult) +185
System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeAction(IAsyncResult asyncResult) +38
System.Web.Mvc.Controller.<BeginExecuteCore>b__1d(IAsyncResult asyncResult, ExecuteCoreState innerState) +29
System.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +67
System.Web.Mvc.Controller.EndExecuteCore(IAsyncResult asyncResult) +52
System.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +36
System.Web.Mvc.Controller.EndExecute(IAsyncResult asyncResult) +38
System.Web.Mvc.MvcHandler.<BeginProcessRequest>b__5(IAsyncResult asyncResult, ProcessRequestState innerState) +43
System.Web.Mvc.Async.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult) +67
System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult) +38
System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +395
System.Web.HttpApplication.ExecuteStepImpl(IExecutionStep step) +197
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +128
Странно, что это работает при использовании сдругой взгляд, тот же контроллер.Я в основном скопировал код для переменной 'link' из действия контроллера другого представления и использовал его повторно.Изменяется только то, что «Details_APExt» заменяется на «Details_APInt» в URL.
Для записи я попытался изменить
var link = "<a href = "\"\\webapp-dev\\Nonconformance\\AP\\Details_APInt\\" + nonconform.ID + "\">Click here to view details</a>";
на
link = "<a href = \"http://webapp-dev/nonconformance/ap/Details_APInt/" + nonconform.ID + "\">Click here to view</a>";
и он выдает тот же результат.
Я убедился, что модель успешно заполняется до визуализации представления.Из того, что я могу сказать, все выглядит хорошо до тех пор, пока оно фактически не отображает представление.
Я также пытался обновить код до
link = "<a href = \"http://webapp-dev/nonconformance/ap/Details_APInt/" + nonconform.ID + "\">Click here to view</a>";
для двух представлений, упомянутых в этом вопросе;Details_APExt и Details_APInt (изменение пути соответственно для Details_APExt).
На этих снимках экрана показано, как отображается гиперссылка в теле письма.Приносим свои извинения, я не могу встраивать фотографии.
Эта гиперссылка успешно работает.
Эта гиперссылка приводит к ошибке.
Как видите, они практически идентичны.
ОБНОВЛЕНИЕ:
Подробности_APInt Представление:
public ActionResult Details_APInt(int id)
{
var result = GetUserInfo();
ViewBag.ReplyFrom = result.Properties["givenname"][0].ToString() + " " + result.Properties["sn"][0].ToString();
TempData["FirstName"] = result.Properties["givenname"][0].ToString();
var nc = db.Nonconforms.Find(id);
var defect = (from x in db.Defects_Caused
where x.Nonconform_ID == nc.Nonconform_ID
select x).FirstOrDefault();
var fromDept = (from f in db.Workcenters
where f.ID == nc.From_WC
select f).FirstOrDefault();
var toDept = (from x in db.Workcenters
where x.ID == nc.To_Dept
select x).FirstOrDefault();
var type = (from t in db.Nonconform_Types
where t.ID == nc.Type
select t).FirstOrDefault();
nc.From = fromDept.Name;
nc.To = toDept.Name;
nc.TypeName = type.Name;
var rolls = (from x in db.Affected_Rolls
where x.Nonconform_ID == nc.Nonconform_ID
select x).ToList();
List<Dictionary<string, string>> affectedRolls = new List<Dictionary<string, string>>();
foreach (var roll in rolls)
{
affectedRolls.Add(GetMESInfo(roll.AC));
}
ViewBag.affectedRolls = affectedRolls;
nc.Replies = (from r in db.Replies
where r.Nonconform_ID == nc.Nonconform_ID
select r).OrderByDescending(x => x.Reply_Date).ToList();
var vm = new ViewModel();
vm.Defect_Caused = defect;
vm.Nonconform = nc;
ViewBag.Time = vm.Nonconform.Date.ToShortTimeString().ToString();
ViewBag.Phone = result.Properties["telephonenumber"][0].ToString();
return View(vm);
}
Details_APExt Представление:
public ActionResult Details_APExt(int id)
{
var result = GetUserInfo();
ViewBag.ReplyFrom = result.Properties["givenname"][0].ToString() + " " + result.Properties["sn"][0].ToString();
TempData["FirstName"] = result.Properties["givenname"][0].ToString();
var nc = db.Nonconforms.Find(id);
var dept = (from f in db.Workcenters
where f.ID == nc.From_Dept
select f).FirstOrDefault();
var type = (from t in db.Nonconform_Types
where t.ID == nc.Type
select t).FirstOrDefault();
nc.From = dept.Name;
nc.TypeName = type.Name;
var rolls = (from x in db.Affected_Rolls
where x.Nonconform_ID == nc.Nonconform_ID
select x).ToList();
List<Dictionary<string, string>> affectedRolls = new List<Dictionary<string, string>>();
foreach (var roll in rolls)
{
affectedRolls.Add(GetMESInfo(roll.AC));
}
ViewBag.affectedRolls = affectedRolls;
nc.Replies = (from r in db.Replies
where r.Nonconform_ID == nc.Nonconform_ID
select r).OrderByDescending(x => x.Reply_Date).ToList();
return View(nc);
}
ОБНОВЛЕНИЕ:
Просто чтобы дать немного больше информации, представления ожидают модель / ViewModel.
Details_APInt (view):
@model Nonconformance.Models.ViewModel
Details_APExt (view):
@model Nonconformance.Models.Nonconform
Единственное, что я могу придумать, это то, что он использует ViewModel, а не просто модель, но я не понимаю, почему это важно, если это такуспешно заполняется перед отображением представления?