3

I've been going around with this for a few days now. I have an existing MVC 4 project that uses entity framework for database creation. The app works as intended but I have a new requirement to add web api to this site. This is a database of quotes and the requirement is to return a simple quote that only contains limited information of the full database entry.

My original model:

    using System;
    using System.Collections.Generic;
    using System.ComponentModel.DataAnnotations;
    using System.Linq;
    using System.Web;

    namespace Exercise4.Models
    {
        public class Quote
        {
            public int QuoteID { get; set; }

            [Required (ErrorMessage = "A Category Field Must be selected or a New one must be Created before continuing")]
            public int CategoryID { get; set; }

            [Display (Name="Quotation")]
            [Required (ErrorMessage = "A Quotation is Required")]
            public string QName { get; set; }

            [Display (Name= "Author")]
            [Required (ErrorMessage = "An Authors Name is Required\n Use 'Unknown' if needed")]
            public string QAuthor { get; set; }


             [Display (Name = "Category")]
             public virtual Category category { get; set; }

             [DisplayFormat(DataFormatString = "{0:d}")]
             public DateTime Date { get; set; }

             public int UserId { get; set; }      
             }
         }

The Simple Quote Model

    using System;
    using System.Collections.Generic;
    using System.ComponentModel.DataAnnotations;
    using System.Linq;
    using System.Web;

    namespace Exercise4.Models
    {
        public class SimpleQuote
        {
            public int Id { get; set; }
            public string Quote { get; set; }
            public string Author { get; set; }
            public  string Category { get; set; }
         }
     }

The Context (*Note the SimpleQuote entry was added automagicly when I scaffold the new QuoteApiController)

    using System;
    using System.Collections.Generic;
    using System.Data.Entity;
    using System.Linq;
    using System.Web;

    namespace Exercise4.Models
    {
        public class QuoteContext : DbContext
        {
            public DbSet<Quote> Quotes { get; set; }
            public DbSet<Category> Categories { get; set; }
            public DbSet<UserProfile> UserIds { get; set; }

            public QuoteContext()
            {
                Configuration.ProxyCreationEnabled = false;
            }

            public DbSet<SimpleQuote> SimpleQuotes { get; set; }

        }
    }

This returns an error when accessing the /api/quoteapi/ page with

The 'ObjectContent`1' type failed to serialize the response body for content type 'application/xml; charset=utf-8'.

Obviously this error occurs because it is trying to return a SimpleQuote Object that doesn't exist in the database.

The API Controller that was created.

    using System;
    using System.Collections.Generic;
    using System.Data;
    using System.Data.Entity;
    using System.Data.Entity.Infrastructure;
    using System.Linq;
    using System.Net;
    using System.Net.Http;
    using System.Web;
    using System.Web.Http;
    using Exercise4.Models;

    namespace Exercise4.Controllers
    {
        public class QuoteApiController : ApiController
        {
            private QuoteContext db = new QuoteContext();

            // GET api/QuoteApi
            public IEnumerable<SimpleQuote> GetSimpleQuotes()
            {   
                return db.SimpleQuotes.AsEnumerable();
            }

            // GET api/QuoteApi/5
            public SimpleQuote GetSimpleQuote(int id)
            {
                SimpleQuote simplequote = db.SimpleQuotes.Find(id);
                if (simplequote == null)
                {
                    throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.NotFound));
                }

                return simplequote;
            }

            protected override void Dispose(bool disposing)
            {
                db.Dispose();
                base.Dispose(disposing);
            }
        }
    }

Where am I going awry. I can't return a model that doesn't exist in the database. If I change the call in the api to return a Quote model that works but I only need to return the quote, author and category as strings. Would I just return the Quote object in the controller, pull out the information I need and then return the SimpleQuote object? Not sure how to do that. Any suggestions?

2 Answers 2

1

You mentioned scaffolding, are you using Code First to create your Database? Also you only want the SimpleQuote for returning the information, it looks like its added to your DB context as a table. When what you really want is to pull the data from the Quote Table and build or extract the information you want and return just that. If you don’t have to return a SimpleQuote Object and just return a string you could write something very simplistic like this.

    public HttpResponseMessage GetSimpleQuote(int id)
    {
        var quote = db.Quotes.Find(id);
        if (quote == null)
        {
            throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.NotFound));
        }

        var output += "ID: " + quote.Id + " Quote: " + quote.Quote +  " Author: " + quote.Author + " Category: " + quote.Category ; 

        var response = new HttpResponseMessage();

        response.Content = new StringContent(output);
        response.Content.Headers.ContentType = new MediaTypeHeaderValue("text/plain");

        return response;

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

1 Comment

@jbolt: Do not make edits to the answer that significantly alters the original context.
0

I 1+ and Accepted @CHammond's response for putting me on the right track. I do need to return a SimpleQuote object. Here is the code I used.

            public SimpleQuote GetSimpleQuote(int id)
    {
        var quote = db.Quotes.Find(id);
        if (quote == null)
        {
            throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.NotFound));
        }

        SimpleQuote output = new SimpleQuote();
        output.Quote = quote.QName;
        output.Author = quote.QAuthor;
        output.Category = db.Categories.Find(quote.CategoryID).CatName;

        return output;

    }

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.