简体   繁体   中英

Error when generating help page webapi2

I am getting an error when trying to generate a help page using MVC5 web api2, I know that when generating the project it generates this for you, however I am getting errors now when trying to click on a link

System.StackOverflowException was unhandled

The error happens on this line formatter.WriteToStreamAsync(type, value, ms, content, null).Wait();

and this is the code where it is happening.

 [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "The exception is recorded as InvalidSample.")]
    public virtual object WriteSampleObjectUsingFormatter(MediaTypeFormatter formatter, object value, Type type, MediaTypeHeaderValue mediaType)
    {
        if (formatter == null)
        {
            throw new ArgumentNullException("formatter");
        }
        if (mediaType == null)
        {
            throw new ArgumentNullException("mediaType");
        }

        object sample = String.Empty;
        MemoryStream ms = null;
        HttpContent content = null;
        try
        {
            if (formatter.CanWriteType(type))
            {
                ms = new MemoryStream();
                content = new ObjectContent(type, value, formatter, mediaType);
                formatter.WriteToStreamAsync(type, value, ms, content, null).Wait();
                ms.Position = 0;
                StreamReader reader = new StreamReader(ms);
                string serializedSampleString = reader.ReadToEnd();
                if (mediaType.MediaType.ToUpperInvariant().Contains("XML"))
                {
                    serializedSampleString = TryFormatXml(serializedSampleString);
                }
                else if (mediaType.MediaType.ToUpperInvariant().Contains("JSON"))
                {
                    serializedSampleString = TryFormatJson(serializedSampleString);
                }

                sample = new TextSample(serializedSampleString);
            }
            else
            {
                sample = new InvalidSample(String.Format(
                    CultureInfo.CurrentCulture,
                    "Failed to generate the sample for media type '{0}'. Cannot use formatter '{1}' to write type '{2}'.",
                    mediaType,
                    formatter.GetType().Name,
                    type.Name));
            }
        }
        catch (Exception e)
        {
            sample = new InvalidSample(String.Format(
                CultureInfo.CurrentCulture,
                "An exception has occurred while using the formatter '{0}' to generate sample for media type '{1}'. Exception message: {2}",
                formatter.GetType().Name,
                mediaType.MediaType,
                UnwrapException(e).Message));
        }
        finally
        {
            if (ms != null)
            {
                ms.Dispose();
            }
            if (content != null)
            {
                content.Dispose();
            }
        }

        return sample;
    }

I got the exact same behavior on a web api project, specifically on a method that received an object as input parameter. For example:

public IHttpActionResult Post(Person person)

The error started showing up after I added a class with the same name (Person) on another unrelated namespace, so the error disappeared by referencing the parameter with the fully qualified namespace:

public IHttpActionResult Post(MyProject.Models.Person person)

Hope this helps someone out.

This may happen if you have a self referencing loop, for some property (or child property) of the parameter object value for which the help page is trying to generate a sample. One way to find out which property is self referencing is by setting a break point here inside the catch scope

catch (Exception e)
    {
        sample = new InvalidSample(String.Format(
            CultureInfo.CurrentCulture,
            "An exception has occurred while using the formatter '{0}' to generate sample for media type '{1}'. Exception message: {2}",
            formatter.GetType().Name,
            mediaType.MediaType,
            UnwrapException(e).Message));
    }

Note: Since the XmlMediaTypeFormatter throws System.StackOverflowException which cannot be caught , This breakpoint will NOT trigger for XmlMediaTypeFormatter, but it will trigger for the JSON formatter.

The JSON formatter should give a message in the following format: Self referencing loop detected for property 'SomeProperty' with type 'SomeAssembly.Test.SomeModel'. Path 'SomeProperty.SomeChildProperty'.

To find a solution to this problem, if you cannot remove the circular reference from the model in question, see Handling Circular Object References from this article https://docs.microsoft.com/en-us/aspnet/web-api/overview/formats-and-model-binding/json-and-xml-serialization#handling_circular_object_references

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM