0

Here, I explain my scenario - I have 2 projects - API (storing the Web API) and APP (storing the Xamarin.Forms). I have used EDMX to create Data models from my database in the API project in API.Models folder. I want to access the API from the APP project and hence have created similar data model classes in my APP project. Things work fine when there are no Foreign Keys present in the model class. As soon as a Foreign Key is added to any of the model classes in API project, consuming the API starts giving me a "Bad Request error"

API.Models Code

namespace API.Models
{
    using System;
    using System.Collections.Generic;

public partial class Lead
{
    public int ID { get; set; }
    public string LeadName { get; set; }
    public Nullable<decimal> AssignedTo { get; set; }
    public virtual User User1 { get; set; } //User is another entity in API.Models
    }
}

APP.Models Code

namespace APP.Models
{
    using System;
    using System.Collections.Generic;

public partial class Lead
{
    public int ID { get; set; }
    public string LeadName { get; set; }
    public Nullable<decimal> AssignedTo { get; set; }
    public virtual User User1 { get; set; }  //User is another entity in APP.Models
    }
}

API Code

namespace APIProject.API
{
    public class IssueLogController : ApiController
    {
        CRMEntities db = new CRMEntities();

        [ResponseType(typeof(Lead))]
        public async Task<IHttpActionResult> PostLead(Lead lead)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }

            db.Lead.Add(lead);

            try
            {
                await db.SaveChangesAsync();
            }
            catch (DbUpdateException)
            {
                if (LeadExists(lead.ID))
                {
                    return Conflict();
                }
                else
                {
                    throw;
                }
            }
            return CreatedAtRoute("DefaultApi", new { id = lead.ID }, lead);
        }

    }
}

Xamarin.Forms code

Lead lead = new Lead();
            lead.LeadName = txtLead.Text.Trim();

        var uri = Constants.URL + "Lead/PostLead/";
        HttpClient client = new HttpClient(new NativeMessageHandler());

        var s = new JsonSerializerSettings { DateFormatHandling = DateFormatHandling.MicrosoftDateFormat };
        var json = JsonConvert.SerializeObject(lead, s);
        var content = new StringContent(json, Encoding.UTF8, "application/json");

        var response = await client.PostAsync(uri, content);
        if (response.IsSuccessStatusCode)
        {
            await DisplayAlert("Message", "Your Lead has been recorded.", "OK");
        }

Any ideas to resolve this?

Nitesh
  • 2,286
  • 2
  • 43
  • 65
  • Not with the info you're providing. A bad request means that you are sending bad data to the API. But depending on how the API is built this could be anything. Ranging from a deserialization error, to you throwing a Bad Request from code yourself. Please include some code and try to be more clear on what you are trying to do. Please also refer to https://stackoverflow.com/help/how-to-ask – Gerald Versluis Nov 14 '17 at 07:39
  • added code. I think it is related to serialization issue where the FK entity User is conflicting between API.Models & APP.Models – Nitesh Nov 14 '17 at 08:13
  • 1
    It's probably due to the BadRequest thrown after `if (!ModelState.IsValid)`. Ergo; the `ModelState` is not valid. Put in a breakpoint there, check the `ModelState` properties to see what is wrong. – Gerald Versluis Nov 14 '17 at 08:14
  • For some unwanted reasons, I am unable to debug my application locally and have to use a staging server. cant debug :( – Nitesh Nov 14 '17 at 08:18
  • 1
    In that case output the right property of the `ModelState` to the logs or turn it into a `return Ok(ModelState.Errors);` so you will know what is wrong. the `Errors` property is just a guess. Not sure from the top of my head what the property is that holds the validation errors. – Gerald Versluis Nov 14 '17 at 08:24
  • Thanks, will give it a try. Do you think the approach used by me to share models between API/APP is correct? – Nitesh Nov 14 '17 at 08:26
  • 2
    It seems kind of redundant since they are _exactly_ the same. But remember: there is no correct way. It all depends on your requirements and needs. If the models will remain identical, why not move them to a common library and use them in both projects? – Gerald Versluis Nov 14 '17 at 08:31
  • @GeraldVersluis Thanks, your comment helped. – Nitesh Nov 14 '17 at 09:41
  • Great! Best of luck with it! – Gerald Versluis Nov 14 '17 at 09:42

1 Answers1

0

As mentioned by @Gerald in comments above, here is what I did in the API code to figure out the error -

 if (!ModelState.IsValid)
        {
            StringBuilder sb = new StringBuilder();
            foreach (var state in ModelState)
            {
                foreach (var error in state.Value.Errors)
                {
                    sb.AppendLine(error.ErrorMessage);
                }
            }
            t_app_issueLog.ID = 1;
            t_app_issueLog.Problem = sb.ToString();
            return CreatedAtRoute("DefaultApi", new { id = lead.ID }, lead);
            //return BadRequest(ModelState);
        }
Nitesh
  • 2,286
  • 2
  • 43
  • 65