Reputation: 91
I am using postal mail to send an order confirmation. It is an MVC4 project. The code was sending email confirmations correctly.
Recently, I have added MVC mobile to the project. Everything works - except when sending a confirmation email when the user is on a mobile device. This is the order confirmation class:
public class OrderConfirmation : Postal.Email
{
public string email { get; set; }
public string partyid { get; set; }
public string GrouponCode { get; set; }
public string originalpartyDate { get; set; }
public string originalpartyStartTime { get; set; }
public string originalpartyTitle { get; set; }
public string originalOrderDate { get; set; }
public bool GrouponWasUpgraded { get; set; }
public decimal GrouponFaceValue { get; set; }
public bool ClassCancelled { get; set; }
public string firstname { get; set; }
public string orderlink { get; set; }
}
And then it gets called like this:
ci = new Email.OrderConfirmation
{
ClassCancelled = false,
email = Email,
firstname = FirstName,
orderlink = "https://website.com/Checkout/Archive?orderlinkid=" + OrderLinkId,
originalpartyDate = DateStart.ToShortDateString(),
originalpartyStartTime = DateStart.ToShortTimeString(),
originalpartyTitle = odt.Party.Title,
partyid = odt.PartyId.ToString()
};
Task task = ci.SendAsync();
In my Global.asax.cs file I detect the mobile devices, and insert the display modes, like this:
protected void Application_Start()
{
DisplayModeProvider.Instance.Modes.Insert(0, new
DefaultDisplayMode("Tablet")
{
ContextCondition = (ctx =>
ctx.Request.UserAgent.IndexOf("iPad", StringComparison.OrdinalIgnoreCase) >= 0 ||
ctx.Request.UserAgent.IndexOf("Android", StringComparison.OrdinalIgnoreCase) >= 0 &&
ctx.Request.UserAgent.IndexOf("mobile", StringComparison.OrdinalIgnoreCase) < 1)
});
DisplayModeProvider.Instance.Modes.Insert(1, new DefaultDisplayMode("iPhone")
{
ContextCondition = (ctx =>
ctx.GetOverriddenBrowser().IsMobileDevice ||
ctx.GetOverriddenUserAgent().IndexOf
("iPhone", StringComparison.OrdinalIgnoreCase) >= 0
)
});
/// omitted the rest of the (standard) code for brevity
}
The error message I get is a generic "Object reference not set to an instance of an object." I have put the stack trace below, as well as an image of when the error code is generated.
iisexpress.exe Error: 0 : 4/15/2014 11:09:33 AMSystem.NullReferenceException: Object reference not set to an instance of an object.
at application.MvcApplication.<Application_Start>b__1(HttpContextBase ctx) in c:\Dropbox\SourceCode\PUYF_NonTFS\PUYF_Website\Application\Global.asax.cs:line 132
at System.Web.WebPages.DefaultDisplayMode.CanHandleContext(HttpContextBase httpContext)
at System.Web.WebPages.DisplayModeProvider.<>c__DisplayClass6.<GetAvailableDisplayModesForContext>b__5(IDisplayMode mode)
at System.Linq.Enumerable.WhereListIterator`1.MoveNext()
at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
at System.Web.Mvc.VirtualPathProviderViewEngine.GetPath(ControllerContext controllerContext, String[] locations, String[] areaLocations, String locationsPropertyName, String name, String controllerName, String cacheKeyPrefix, Boolean useCache, String[]& searchedLocations)
at System.Web.Mvc.VirtualPathProviderViewEngine.FindView(ControllerContext controllerContext, String viewName, String masterName, Boolean useCache)
at System.Web.Mvc.ViewEngineCollection.<>c__DisplayClassc.<FindView>b__a(IViewEngine e)
at System.Web.Mvc.ViewEngineCollection.Find(Func`2 lookup, Boolean trackSearchedPaths)
at System.Web.Mvc.ViewEngineCollection.FindView(ControllerContext controllerContext, String viewName, String masterName)
at Postal.EmailViewRenderer.CreateView(String viewName, ControllerContext controllerContext)
at Postal.EmailViewRenderer.Render(Email email, String viewName)
at Postal.EmailService.CreateMailMessage(Email email)
at Postal.EmailService.SendAsync(Email email)
at Postal.Email.SendAsync()
at Application.Models.Order.SendConfirmation(ArtStoreEntities dbcontext) in
c:\Dropbox\SourceCode\PUYF_NonTFS\PUYF_Website\Application\Models\Order.cs:line 134
It seems, when postal is generating the view, it hits the application_start in the global.asax file, and because the useragent properties are null - it generates the error. I tried putting a try catch block around the specific code in the application_start procedure - but that does not work.
I need help how to tell MVC or Postal not to bother with the displaymodes. Any suggestions?
Upvotes: 1
Views: 753
Reputation: 91
This is what I ended up doing:
DisplayModeProvider.Instance.Modes.Insert(0, new
DefaultDisplayMode("Tablet"){
ContextCondition = (ctx =>
ctx.Request.UserAgent != null &&
(
ctx.Request.UserAgent.IndexOf("iPad", StringComparison.OrdinalIgnoreCase) >= 0 ||
ctx.Request.UserAgent.IndexOf("Android", StringComparison.OrdinalIgnoreCase) >= 0 &&
ctx.Request.UserAgent.IndexOf("mobile", StringComparison.OrdinalIgnoreCase) < 1))
});
DisplayModeProvider.Instance.Modes.Insert(1, new DefaultDisplayMode("iPhone"){
ContextCondition = (ctx =>
ctx.Request.UserAgent != null &&
(
ctx.GetOverriddenBrowser().IsMobileDevice ||
ctx.GetOverriddenUserAgent().IndexOf
("iPhone", StringComparison.OrdinalIgnoreCase) >= 0
)
)
});
Upvotes: 1
Reputation: 5451
Could you try making the ContextCondition
return false when ctx.Request.UserAgent
is null?
Upvotes: 0