6

I'm creating a static class with static methods for helping the controllers to do their job. When build the application I get the following error:

Error 40 'System.Web.Mvc.Controller.Content(string)' is inaccessible due to its protection level"

Any idea how to solve this problem?

Notes: It's a c# mvc aplication

public static ActionResult GetAlbumJSON(AlbumVO album)
{
    return Controller.Content(
        JsonConvert.SerializeObject(new
        {
            max_car = @ABookClient.maxCharsProjecName,
            trans_img = @ABookClient.Transparent_Image,
            show_description = @ABookClient.Show_Product_Description,
            product_type = "Album",
            obj = CreateObjAlbumVO(album),
        })
    );
}
8
  • 1
    Make your Content method public Commented Aug 31, 2015 at 13:39
  • 3
    You better create your own base controller that derives from System.Web.Mvc.Controller and put your helpers there so that you won't have inaccessibility problems. Commented Aug 31, 2015 at 13:42
  • Why not simply return Json(new { max_car ... })? Commented Aug 31, 2015 at 13:42
  • 1
    @haim770 Yes, i know that i can do that, and it is a solution. But what i really want it is the function return a ActionResult and not a string Commented Aug 31, 2015 at 13:46
  • 1
    @RicardoRocha, you can (and sometimes should) delegate work to other components. But, by-design, the actual creation of the ActionResult has to be done in the controller itself. Commented Aug 31, 2015 at 13:55

2 Answers 2

4

Content method is protected internal, so you can't use it outside of controller. Controller.Content Method. Most probably your static class violates SRP principle. Let him do his job (initializing, serializing,...) and controller - controller's job - return result to the client.

protected internal ContentResult Content(string content)

It would look smth like:

public static class MyHelper
{
    public static object GetAlbum(AlbumVO album)
    {
        return new
            {
                max_car = @ABookClient.maxCharsProjecName,
                trans_img = @ABookClient.Transparent_Image,
                show_description = @ABookClient.Show_Product_Description,
                product_type = "Album",
                obj = CreateObjAlbumVO(album),
            };
    }
}

public class AlbumController : Controller
{
    public ActionResult GetAlbums(int id)
    {
        var album = Context.GetAlbum(id);
        var convertedResult = MyHelper.GetAlbum(album);
        return Json(convertedResult);
    }
}

Also I'd advice to take a look at AutoMapper for creating client response objects

Sign up to request clarification or add additional context in comments.

2 Comments

You have right about the protect internal thing. But the code that you had post it's wrong. It equal to my problem so it will not resolve anything :S See the comments bellow the question
@RicardoRocha my bad. Fixed. Now helper doesn't use Content method
2

I think this is valid case for a view-model for a JSON result since you do want a separation between the Domain model and the data sent back to the client. Using a view model also gives you a proper place to put this mapping between the domain model and the view (the JSON) so you don't need to delegate to a helper class.

public class AlbumModel
{
    [JsonProperty(PropertyName = "max_car")]
    public int MaxChars { get; private set; }
    [JsonProperty(PropertyName = "trans_img")]
    public string TransparentImage { get; private set; }
    [JsonProperty(PropertyName = "product_type")]
    public string ProductType { get; private set; }
    [JsonProperty(PropertyName = "obj")]
    public AlbumInfo Object { get; private set; }
    [JsonProperty(PropertyName = "show_description")]
    public bool ShowProductDescription { get; private set; }

    public AlbumModel(AlbumVO album)
    {
        MaxChars = album.maxCharsProjecName;
        TransparentImage = album.Transparent_Image;
        ShowProductDescription = album.Show_Product_Description;
        ProductType = "Album";
        Object = new AlbumInfo(album);
    }
}

The AlbumInfo class provides additional mappings for your JSON result, which becomes the "obj" property sent back to the client.

public class AlbumInfo
{
    // ... define properties here
    public AlbumInfo(AlbumVO album)
    {
        // ... map properties here
    }
}

And your controller becomes nice and clean:

public class AlbumController : Conrtoller
{
    public ActionResult GetAlbums(int id)
    {
        var album = Context.GetAlbum(id);
        var model = new AlbumModel(album);
        return Json(model);
    }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.