2
votes

When submitting the form, I receive the following error:

Exception Details

System.NullReferenceException: Object reference not set to an instance of an object. at Microsoft.Azure.Documents.Document.get_AttachmentsLink() at Microsoft.Extensions.Internal.PropertyHelper.CallNullSafePropertyGetter[TDeclaringType,TValue](Func`2 getter, Object target) at Microsoft.AspNetCore.Mvc.Internal.DefaultComplexObjectValidationStrategy.Enumerator.MoveNext() at Microsoft.AspNetCore.Mvc.ModelBinding.Validation.ValidationVisitor.VisitChildren(IValidationStrategy strategy) at Microsoft.AspNetCore.Mvc.ModelBinding.Validation.ValidationVisitor.VisitComplexType() at Microsoft.AspNetCore.Mvc.ModelBinding.Validation.ValidationVisitor.Visit(ModelMetadata metadata, String key, Object model) at Microsoft.AspNetCore.Mvc.Internal.DefaultControllerArgumentBinder.d__8.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.AspNetCore.Mvc.Internal.DefaultControllerArgumentBinder.d__6.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.d__22.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Rethrow(ResourceExecutedContext context) at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted) at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.d__20.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.AspNetCore.Builder.RouterMiddleware.d__4.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.VisualStudio.Web.BrowserLink.BrowserLinkMiddleware.d__7.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.d__7.MoveNext()

I have tried supplying the form with hidden values for every property associated with the model and Microsoft.Azure.Documents.Document but with the same result. In addition, I have changed the parameter type in the POST to dynamic, which did avoid the exception.

TrainingModel (Model)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Newtonsoft.Json;

namespace Training.Models
{
    public class TrainingModel : Microsoft.Azure.Documents.Document
    {

    [JsonProperty(PropertyName = "text")]
    public string Text { get; set; }

    [JsonProperty(PropertyName = "last_updated")]
    public DateTime? LastUpdated { get; set; }

    [JsonProperty(PropertyName = "training_sentiment")]
    public string TrainingSentiment { get; set; }

    [JsonProperty(PropertyName = "sentiment")]
    public string Sentiment { get; set; }

    [JsonProperty(PropertyName = "score")]
    public string SentimentScore { get; set; }

    [JsonProperty(PropertyName = "entities")]
    public List<Entity> Entities { get; set; }

    public class Entity
    {

        [JsonProperty(PropertyName = "start")]
        public long Start { get; set; }

        [JsonProperty(PropertyName = "end")]
        public long End { get; set; }

        [JsonProperty(PropertyName = "value")]
        public string Value { get; set; }

        [JsonProperty(PropertyName = "orth")]
        public string Orth { get; set; }

        [JsonProperty(PropertyName = "label")]
        public string Label { get; set; }

        }

    }
}

Document (View)

<form asp-controller="Tweet" asp-action="Document" method="post" asp-anti-forgery="false">

                            <!-- Tweet Text -->
                            <div class="form-group">
                                <label asp-for="Text" class="control-label">
                                    Document Text
                                </label>
                                <div class="well">
                                    @Html.Raw(Model.Text)
                                </div>
                            </div>

                            <!-- Entities -->
                            <div class="form-group tags">
                                <label asp-for="Entities">
                                    Name Entity Recognition
                                </label>
                                <div class="form-group">
                                    <p>Using your mouse, highlight some text in the document's text field to add entities to the document.</p>
                                </div>
                                <div class="form-group">
                                    <div class="col-md-2">
                                        <div>
                                            <label>
                                                Start
                                            </label>
                                        </div>
                                    </div>
                                    <div class="col-md-2">
                                        <div>
                                            <label>
                                                End
                                            </label>
                                        </div>
                                    </div>
                                    <div class="col-md-3">
                                        <div>
                                            <label>
                                                Label
                                            </label>
                                        </div>
                                    </div>
                                    <div class="col-md-4">
                                        <div>
                                            <label>
                                                Value
                                            </label>
                                        </div>
                                    </div>
                                    <div class="col-md-1">
                                        <div></div>
                                    </div>
                                </div>
                                @if(Model.Entities != null && Model.Entities.Count > 0) { 
                                    for (int i = 0; i < Model.Entities.Count; i++)
                                    {
                                        <div class="form-group row tag-row">
                                            <div class="col-md-2">
                                                <div>
                                                    @Html.TextBoxFor(model => model.Entities[i].Start, null, new { @class = "form-control" })
                                                </div>
                                            </div>
                                            <div class="col-md-2">
                                                <div>
                                                    @Html.TextBoxFor(model => model.Entities[i].End, null, new { @class = "form-control" })
                                                </div>
                                            </div>
                                            <div class="col-md-3">
                                                <div>
                                                    @Html.TextBoxFor(model => model.Entities[i].Label, null, new { @class = "form-control" })
                                                </div>
                                            </div>
                                            <div class="col-md-4">
                                                <div>
                                                    @Html.TextBoxFor(model => model.Entities[i].Value, null, new { @class = "form-control" })
                                                </div>
                                            </div>
                                            <div class="col-md-1">
                                                <div>
                                                    <button type="button" class="btn btn-default" data-toggle='tag-row'>
                                                        <i class='fa fa-trash-o'></i>
                                                    </button>
                                                </div>
                                            </div>
                                        </div>
                                    }
                                }
                            </div>

                            <!-- Sentiment Tag -->
                            <div class="form-group">
                                <label asp-for="TrainingSentiment" class="control-label">
                                    Sentiment Tag
                                </label>
                                <div>
                                    <div class="btn-toolbar" data-toggle="buttons">
                                        <div class="btn-group">
                                            <label class="btn btn-default @((Model.TrainingSentiment.ToLower() == "positive") ? "active" : string.Empty)">
                                                <input asp-for="TrainingSentiment" type="radio" value="positive" /> <span class="sentimentText">Positive</span>
                                            </label>
                                            <label class="btn btn-default @((Model.TrainingSentiment.ToLower() == "negative") ? "active" : string.Empty)">
                                                <input asp-for="TrainingSentiment" type="radio" value="negative" /> <span class="sentimentText">Negative</span>
                                            </label>
                                        </div>
                                        <div class="btn-group">
                                            <label class="btn btn-default">
                                                <input asp-for="TrainingSentiment" type="radio" value="" /> Reset
                                            </label>
                                        </div>
                                    </div>
                                </div>
                            </div>

                            <div class="ln_solid"></div>

                            <!-- Buttons -->
                            <div class="row text-center">
                                <button type="submit" class="btn btn-primary">Submit</button>
                            </div>

                            <!-- Hidden Data -->
                            <input asp-for="Id" type="hidden" />

                        </form>

TweetController

    public IActionResult Document()
    {
        var model = ConnectionModel.Tweets.SelectTagged(1)[0];
        return View(model);
    }

    [HttpPost]
    public IActionResult Document(TrainingModel model)
    {
        if (model == null)
            return Json(new { error = "null model." });


        return Json(model);
    }
1

1 Answers

2
votes

You should not be extending your classes from Microsoft.Azure.Documents.Document. This class is essentially a wrapper around a dynamic response from the Cosmos service and includes properties (like AttachmentLinks) that your entities should not need to know about. Remove this base class from your models and consider using your own simple DocumentBase class. Something like this would probably do the trick.

public class DocumentBase
{
    [JsonProperty(PropertyName = "id")]
    public string Id { get; set; }
}