2017-08-12 10 views
0

私はこれを数時間悩ましています。WebApi 2とEntityFrameworkを使用しているときにjsonのみが返されるようにします

私はWebApi 2とEntity Framework 6.1.3を使用しています。私はこのチュートリアルに従っています: https://docs.microsoft.com/en-us/aspnet/web-api/overview/data/using-web-api-with-entity-framework/

私はjsonだけを返したいと思います。私がURL http://localhost:11440/Api/Contactsを押すと。次のエラーが発生しています: 'ObjectContent`1'タイプは、コンテンツタイプ 'application/xml;のレスポンス本文をシリアル化できませんでした。 charset = utf-8 'となります。

Iは、次のモデルとコントローラ定義されている:

Address.cs

namespace Blah_Application.Models 
{ 
    public class Address 
    { 
     public int AddressID { get; set; } 

     public int ContactID { get; set; } 

     public string Street { get; set; } 

     public string City { get; set; } 

     public string State { get; set; } 

     public string Country { get; set; } 

     public string ZipCode { get; set; } 

     public double Latitude { get; set; } 

     public double Longitude { get; set; } 

     public virtual Contact Contact { get; set; } 
    } 
} 

Contact.cs

using System.Collections.Generic; 

namespace Blah_Application.Models 
{ 
    public class Contact 
    { 
     public Contact() 
     { 
      Phones = new HashSet<Phone>(); 
      Addresses = new HashSet<Address>(); 
     } 

     public int ContactID { get; set; } 

     public string Name { get; set; } 

     public string Company { get; set; } 

     public bool Favorite { get; set; } 

     public string SmallImageUrl { get; set; } 

     public string LargeImageUrl { get; set; } 

     public string Email { get; set; } 

     public string Website { get; set; } 

     public string BirthDate { get; set; } 

     public virtual ICollection<Phone> Phones { get; set; } 

     public virtual ICollection<Address> Addresses { get; set; } 
    } 
} 

Phone.cs

namespace Ecitslos_Application.Models 
{ 
    public enum PhoneType { Home, Work, Mobile} 

    public class Phone 
    { 
     public int PhoneID {get; set;} 

     public int ContactID { get; set; } 

     public PhoneType PhoneType { get; set; } 

     public string Number { get; set; } 

     public virtual Contact Contact { get; set; } 
    } 
} 

ContactsController.csを

using System.Data.Entity; 
using System.Data.Entity.Infrastructure; 
using System.Linq; 
using System.Net; 
using System.Web.Http; 
using System.Web.Http.Description; 
using Blah_Application.Models; 

namespace Ecitslos_Application.Controllers 
{ 
    public class ContactsController : ApiController 
    { 
     private Ecitslos_ApplicationContext db = new 
     Ecitslos_ApplicationContext(); 

     // GET: api/Contacts 
     public IQueryable<Contact> GetContacts() 
     { 
      return db.Contacts; 
     } 

     // GET: api/Contacts/5 
    [ResponseType(typeof(Contact))] 
    public IHttpActionResult GetContact(int id) 
    { 
     Contact contact = db.Contacts.Find(id); 
     if (contact == null) 
     { 
      return NotFound(); 
     } 

     return Ok(contact); 
    } 

    // PUT: api/Contacts/5 
    [ResponseType(typeof(void))] 
    public IHttpActionResult PutContact(int id, Contact contact) 
    { 
     if (!ModelState.IsValid) 
     { 
      return BadRequest(ModelState); 
     } 

     if (id != contact.ContactID) 
     { 
      return BadRequest(); 
     } 

     db.Entry(contact).State = EntityState.Modified; 

     try 
     { 
      db.SaveChanges(); 
     } 
     catch (DbUpdateConcurrencyException) 
     { 
      if (!ContactExists(id)) 
      { 
       return NotFound(); 
      } 
      else 
      { 
       throw; 
      } 
     } 

     return StatusCode(HttpStatusCode.NoContent); 
    } 

    // POST: api/Contacts 
    [ResponseType(typeof(Contact))] 
    public IHttpActionResult PostContact(Contact contact) 
    { 
     if (!ModelState.IsValid) 
     { 
      return BadRequest(ModelState); 
     } 

     db.Contacts.Add(contact); 
     db.SaveChanges(); 

     return CreatedAtRoute("DefaultApi", new { id = contact.ContactID }, contact); 
    } 

    // DELETE: api/Contacts/5 
    [ResponseType(typeof(Contact))] 
    public IHttpActionResult DeleteContact(int id) 
    { 
     Contact contact = db.Contacts.Find(id); 
     if (contact == null) 
     { 
      return NotFound(); 
     } 

     db.Contacts.Remove(contact); 
     db.SaveChanges(); 

     return Ok(contact); 
    } 

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

    private bool ContactExists(int id) 
    { 
     return db.Contacts.Count(e => e.ContactID == id) > 0; 
    } 
    } 
} 

答えて

0

デフォルトで設定されているXMLフォーマッタを無効にする必要があります。 WebApiConfigクラスに次の行を追加します。

public static class WebApiConfig { 
    public static void Register(HttpConfiguration config) { 
     //route config etc. goes here 

     //disable xml serialization 
     config.Formatters.Remove(config.Formatters.XmlFormatter); 

     //prevent infinite recusion 
     config.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore; 
    } 
} 
+0

これは私のためには機能しません。私が試してみると、エラーが発生しています:プロパティ 'Contact'がタイプ 'System.Data.Entity.DynamicProxies.Contact_F0D869DA35A5D79D9FC7459ECA71E46F93E7CACF4EB08F9DCCF7A7DCCF99E1D3 – hikerclimb

+0

@hikerclimbで検出された自己参照ループです。これはJSONのみを返すこととは別の問題です。私はそれを処理するための2番目の設定を含むように私の答えを編集しました。 – user2880616

+0

@hikerclimbは 'Phone'に' Contact'があり、 'Contact'で' Phone'をインスタンス化しているからです。 –

0

私のプロジェクトでこれをやっている方法は次のとおりです。あなたが正しい方向にポインタを得ることを望みます。

// GET: api/Contacts/5 
    <Route("~/api/Contacts/{id}")> 
    <HttpGet> 
    public HttpResponseMessage GetContact(int id) 
    { 
     Contact contact = db.Contacts.Find(id); 
     if (contact == null) 
     { 
      Return Request.CreateResponse(HttpStatusCode.NotFound, "Contact Id not found", Configuration.Formatters.JsonFormatter); 
     } 
Return Request.CreateResponse(HttpStatusCode.OK, contact, Configuration.Formatters.JsonFormatter); 

    } 

はまた、あなたがPhoneContactを持っていると、あなたはContactPhoneをインスタンス化しています。これにより、循環依存性が生じる可能性があります。

関連する問題