moonpyk / mvcdonutcaching

ASP.NET MVC Extensible Donut Caching brings donut caching to ASP.NET MVC 3 and later. The code allows you to cache all of your page apart from one or more Html.Actions which can be executed every request. Perfect for user specific content.
https://github.com/moonpyk/mvcdonutcaching
MIT License
142 stars 50 forks source link

DataContractSerializer seems is not respecting [EnumMember] attribute and causing errors with serializing view's RouteData. #24

Closed Alkapin closed 10 years ago

Alkapin commented 10 years ago

Got this error:

Type 'PAM_Web.Views.People.ViewModels.PeopleViewMode' with data contract name 'PeopleViewMode:http://schemas.datacontract.org/2004/07/PAM_Web.Views.People.ViewModels' is not expected. Consider using a DataContractResolver or add any types not known statically to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding them to the list of known types passed to DataContractSerializer.

Tracked it to the error on this line _serialiser.WriteObject(memoryStream, actionSettings):

    public string Serialise(ActionSettings actionSettings)
    {
        using (var memoryStream = new MemoryStream())
        {
           _serialiser.WriteObject(memoryStream, actionSettings);
            return Encoding.UTF8.GetString(memoryStream.ToArray());
        }
    }

Seems that problem is that one of the route values i get at this point using String representation on the PAM_Web.Views.People.ViewModels.PeopleViewMode enum member. I have tried to decorate enum with [DataContact] and enum member with:

[EnumMember(Value = "0")]

doesn't work as well. I still get enum's member name here.

Found info here http://stackoverflow.com/questions/14391725/how-do-i-serialize-an-enum-value-as-a-string

"As seen in a number of other post, the .NET JsonSerializer or DataContractJsonSerializer don't respect the EnumMember attribute, but use the numeric value for the different members of the enumeration. So writing your own custom serializer or use some 3rd party libraries are the way forward."

And suggesting to use Newtonsoft.Json. What do you think?

Thanks.

moonpyk commented 10 years ago

I got this issue in the past too, I got around by casting my enum values to int in route values, MVC's default modelbinder / route binder works seamlessly with numeric representations of enum values.

@Url.Action("Foo", "Bar", new {foobar=MyEnum.MyEnumValue})

->

@Url.Action("Foo", "Bar", new {foobar=(int)MyEnum.MyEnumValue})

I want to avoid adding external libraries dependencies to MvcDonutCaching (say external to the .NET framework itself).

Alkapin commented 10 years ago

Thanks for the reply. I ended up doing the same.