1

I have an asp.net 4.5 application that is a wizard UI that generates a report at the end. I am using the MVC Futures plugin to serialize and pass the model around between forms. I can click all the way through and generate the report. I've also hit F5 and refreshed and it will repost the form data from the previous request and reload the form.

My problem is sometimes, usually after waiting a few minutes, if I try to hit F5 on the page again, instead of it regenerating the report, I get the following error:

SerializationException: Deserialization failed.

It seems to be that the browser may have somehow forgotten the previous request and is trying to refresh the page without resubmitting the form. Any ideas as to what is going on? I will try to reproduce this issue by resubmitting the form right away, then waiting a few minutes and doing it again and watching what gets posted each time, using Fiddler.

Does anybody have any ideas as to what could be the issue here?

Update (1/3/2014):

Here's the post method to generate the report:

[HttpPost]
public ActionResult GenerateReport([Deserialize] WizardModel wizardModel, string providerId = null, string providerName = null)
{
    var model = new ReportModel();
    if (!String.IsNullOrEmpty(providerId))
    {
        wizardModel.Providers = new List<NameValue>(){ new NameValue() { Name = providerName, Value = providerId }};
        model.AutoPrint = true;
    }

    var param = new MeasureParams()
    {
        Key = wizardModel.CriteriaKeys.ToArray(),
        ProviderIds = (wizardModel.Providers != null ? wizardModel.Providers.Select(x => x.Value).ToArray() : null),
        StartDate = (wizardModel.StartDate),
        StartDateAsString = (wizardModel.StartDate).ToString(),
        EndDate = (wizardModel.EndDate),
        EndDateAsString = (wizardModel.EndDate).ToString()
    };

    var results = _measureService.CalculateMeasures(param);

    model.WizardModel = wizardModel;
    model.Results = new List<List<ResultsModel>>();

    model.Results.AddRange(MeasureResultsMapper.MapMeasurementsResultToHierarchicalList(results));
    if (wizardModel.IsDetailedReport)
    {
        return View("DetailedReport", model);
    }
    return View("SummaryReport", model);                
}

There's nothing special in the view page itself. It doesn't even have the serialized object. That was in the previous review page. I can post part of that page:

@{ Html.BeginForm("GenerateReport", "Wizard", FormMethod.Post, new {id = "reviewForm"});}
@Html.Serialize("wizardModel", Model)
@{Html.EndForm();}

Full Stack Trace:

Server Error in '/' Application.


Object reference not set to an instance of an object. Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.NullReferenceException: Object reference not set to an instance of an object.

Source Error: An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.

Stack Trace:

[NullReferenceException: Object reference not set to an instance of an object.] System.Web.Security.MachineKey.Decode(String encodedData, MachineKeyProtection protectionOption) +268 Microsoft.Web.Mvc.MachineKeyWrapper.Decode(String encodedData, MachineKeyProtection protectionOption) +41 Microsoft.Web.Mvc.MvcSerializer.Deserialize(String serializedValue, SerializationMode mode, IMachineKey machineKey) +175

[SerializationException: Deserialization failed. Verify that the data is being deserialized using the same SerializationMode with which it was serialized. Otherwise see the inner exception.] Microsoft.Web.Mvc.MvcSerializer.Deserialize(String serializedValue, SerializationMode mode, IMachineKey machineKey) +384 Microsoft.Web.Mvc.MvcSerializer.Deserialize(String serializedValue, SerializationMode mode) +70 Microsoft.Web.Mvc.DeserializingModelBinder.BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) +293 System.Web.Mvc.ControllerActionInvoker.GetParameterValue(ControllerContext controllerContext, ParameterDescriptor parameterDescriptor) +317 System.Web.Mvc.ControllerActionInvoker.GetParameterValues(ControllerContext controllerContext, ActionDescriptor actionDescriptor) +117 System.Web.Mvc.Async.<>c_DisplayClass25.b_1e(AsyncCallback asyncCallback, Object asyncState) +446 System.Web.Mvc.Async.WrappedAsyncResult1.Begin(AsyncCallback callback, Object state, Int32 timeout) +130 System.Web.Mvc.Async.AsyncControllerActionInvoker.BeginInvokeAction(ControllerContext controllerContext, String actionName, AsyncCallback callback, Object state) +302 System.Web.Mvc.<>c__DisplayClass1d.<BeginExecuteCore>b__17(AsyncCallback asyncCallback, Object asyncState) +30 System.Web.Mvc.Async.WrappedAsyncResult1.Begin(AsyncCallback callback, Object state, Int32 timeout) +130 System.Web.Mvc.Controller.BeginExecuteCore(AsyncCallback callback, Object state) +381 System.Web.Mvc.Async.WrappedAsyncResult1.Begin(AsyncCallback callback, Object state, Int32 timeout) +130 System.Web.Mvc.Controller.BeginExecute(RequestContext requestContext, AsyncCallback callback, Object state) +317 System.Web.Mvc.Controller.System.Web.Mvc.Async.IAsyncController.BeginExecute(RequestContext requestContext, AsyncCallback callback, Object state) +15 System.Web.Mvc.<>c__DisplayClass8.<BeginProcessRequest>b__2(AsyncCallback asyncCallback, Object asyncState) +71 System.Web.Mvc.Async.WrappedAsyncResult1.Begin(AsyncCallback callback, Object state, Int32 timeout) +130 System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContextBase httpContext, AsyncCallback callback, Object state) +249 System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContext httpContext, AsyncCallback callback, Object state) +49 System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.BeginProcessRequest(HttpContext context, AsyncCallback cb, Object extraData) +16 System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +301 System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +155

Dan Csharpster
  • 2,662
  • 1
  • 26
  • 50
  • 1
    Please provide some code. – ataravati Jan 03 '14 at 01:24
  • I posted the Post action and the form from the review page. Please let me know if you'd like to see anything else. – Dan Csharpster Jan 03 '14 at 19:46
  • 1
    Is this on a webfarm? – mxmissile Jan 03 '14 at 21:38
  • I am seeing this as I develop locally. The production version is hosted on Azure, but I haven't seen this error on there yet. That's not to say someone else hasn't and didn't report it. – Dan Csharpster Jan 03 '14 at 21:47
  • Looking at the Deserialize src it looks like `SerializationException` loads up the `InnerException`, what is that exception? – mxmissile Jan 03 '14 at 21:48
  • The Deserialize process is two steps, first step it uses the machinekey to decrypt the data then the it builds the graph from the decrypted data. That error could come from either step, the InnerException should give some hints. – mxmissile Jan 03 '14 at 21:53
  • Thanks @mxmissile! I've updated my question to now include the stace trace. I still am seeing this error, but cannot figure out how to reproduce it 100% of the time, which I why I cannot yet post and 'steps to reproduce' for the issue. – Dan Csharpster Jan 13 '14 at 15:24

1 Answers1

1

Your are using a wrong syntax to render your form. Replace your form with this:

@using(Html.BeginForm("GenerateReport", "Wizard", FormMethod.Post, new {id = "reviewForm"}))
{
    @Html.Serialize("wizardModel", Model)
}

Unlike Html.EndForm(), Html.BeginForm() is not a void function. You can't call it like that. If you want to render the form like that, you should do it like below, but I wouldn't recommend that, as it's not easy to read:

@Html.BeginForm()
@Html.Serialize("wizardModel", Model)
@{Html.EndForm();}
ataravati
  • 8,891
  • 9
  • 57
  • 89
  • If his form tags are wrong, I don't think it would work at all. – mxmissile Jan 03 '14 at 21:24
  • The form tags are wrong, and should not work. He needs to update his question with the correct code. – ataravati Jan 03 '14 at 22:13
  • @ataravati, thanks for the reply. While you are correct that BeginForm is not a void function, it can be used like I am doing. The form works 95% of the time with the syntax I posted. Thanks for the help, but I think something else is at play here that is breaking the deserialization 5% of the time. – Dan Csharpster Jan 06 '14 at 22:34