2015-04-03 4 views
0

Я работаю над созданием приложения Windows Phone 8.1, которое использует веб-API и Entity Framework для подключения к базе данных SQL. С моей текущей настройкой у меня есть объекты данных для моих объектов в моем проекте служб (которые содержат свойство идентификатора PK) и модели в моем проекте клиентского телефона (которые не содержат свойства идентификатора PK, чтобы включить автоинкремент, когда новый член создается. Я пытаюсь написать метод services, который возвращает значение memberID (PK объекта-члена), когда ему присваивается имя пользователя. Однако, когда я это делаю, возникает следующая ошибка:Получите значение PK, передав значение, отличное от PK, используя EntityFramework

System.InvalidCastException: невозможно лить объект типа «System.Net.Http.StreamContent» для ввода «System.IConvertible».

Я не уверен, что я пытаюсь сделать что-то, что не работает, или, если есть намного более простой способ сделать это, но мой код работает успешно. Вышеприведенная ошибка - ошибка во время выполнения. Вот код, который я для меня ING для моих соответствующих классов:

Это метод, который вызывает мой сервер из бэкэнда моего клиента:

public async void GetMembers(String currUser, String currPass) 
    { 
     using (var client = new HttpClient()) 
     { 
      //MembersListBox.Items.Add("using block entered"); 
      client.BaseAddress = new Uri("http://nflff.azurewebsites.net"); 
      client.DefaultRequestHeaders.Accept.Clear(); 
      client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); 
      //MembersListBox.Items.Add("client's defaultrequestheaders done"); 

      //gets all members from table 
      HttpResponseMessage response = await client.GetAsync("api/Members"); 
      //MembersListBox.Items.Add("after response reached"); 
      if (response.IsSuccessStatusCode) 
      { 
       //reads all member objs from table as a json string 
       string s = await response.Content.ReadAsStringAsync(); 
       //how can we pass the user's login credentials (including ID) to other pages? via HttpClient? 
       //converts string of members into a list of member objs 
       var deserializedResponse = JsonConvert.DeserializeObject<List<Members>>(s); 
       foreach (Members member in deserializedResponse) 
       { 
        //if current member matches a member found in list 
        if(member.compareUserAndPassword(currUser, currPass)) { 
         MembersListBox.Items.Add(currUser + " and " + currPass + " found."); 
         MembersListBox.Items.Add(member.userName + " " + member.password); 
         Members currMember = member; //this works 
         MembersListBox.Items.Add("Current member: " + currMember.ToString()); 
         //how should memberID be remembered for user? 
         client.DefaultRequestHeaders.Authorization = CreateBasicHeader(currUser, currPass); 
         MembersListBox.Items.Add(client.DefaultRequestHeaders.Authorization); 
         HttpResponseMessage memResponse = await client.GetAsync("api/Members/" + currUser); 
         if (memResponse.IsSuccessStatusCode) 
         { 
          MembersListBox.Items.Add("memResponse successful"); 
         } 
         //should only go to home page if successful 
         //int memID = Convert.ToInt32(await client.GetAsync("api/Members?MemberStr=" + currUser)); 
         HttpResponseMessage thisMember = await client.GetAsync("api/Members?MemberStr=" + currUser); 
         var con = thisMember.Content; 
         var head = thisMember.Headers; 
         var rm = thisMember.RequestMessage; 
         int memID = Convert.ToInt32(thisMember.Content);//THIS IS THE LINE THAT GENERATES THE ERROR 
         //will need to call server's getidbyname method and pass result instead of currMember.memberID 
         //this.Frame.Navigate(typeof(HomeHub), currMember.memberID); 
         this.Frame.Navigate(typeof(HomeHub), memID); 
        } 

       } 

      } 
      //MembersListBox.Items.Add(Members.MembersList.Count); 
      foreach (var member in Members.MembersList) 
      { 
       // MembersListBox.Items.Add(member.ToString()); 
      } 
     } 
    } 

Вот мой контроллер от моего проекта услуги:

public class MembersController : ApiController 
{ 
    private GatoradeShowerDB db = new GatoradeShowerDB(); 

    // GET: api/Members 
    public IQueryable<Member> GetMembers() 
    { 
     return db.Members; 
    } 

    // GET: api/Members/5 
    [ResponseType(typeof(Member))] 
    public async Task<IHttpActionResult> GetMember(int id) 
    { 
     Member member = await db.Members.FindAsync(id); 
     if (member == null) 
     { 
      return NotFound(); 
     } 

     return Ok(member); 
    } 

    //GET: api/Members?MemberStr={memberStr} 
    [ResponseType(typeof(Member))] 
    public async Task<T> GetMemberIDByName<T>(String MemberStr) where T : struct 
    { 
     //var member = JsonConvert.DeserializeObject<Member>(MemberStr); 
     //Member member = await db.Members.FindAsync(MemberStr); 
     //var userId = ...; 
     var member = await db.Members.Where(x => x.UserName == MemberStr).ToListAsync(); 
     if (member == null) 
     { 
      return (T)Convert.ChangeType(NotFound(), typeof(T)); 
     } 
     return (T)Convert.ChangeType(member[0].MemberID, typeof(T)); 
     //return member[0].MemberID; //hopefully gets id of first member in async list and returns it 
     //return Ok(member); 
    } 

//other methods 
} 

Кроме того, вот мой клиент -side:

public class Members 
{ 
    //[JsonProperty("MemberID")] 
    //public int memberID { get; private set; } 
    [JsonProperty("FirstName")] 
    private string firstName { get; set; } 
    [JsonProperty("LastName")] 
    private string lastName { get; set; } //both names should be optional 
    [JsonProperty("UserName")] 
    public string userName { get; private set; } //note: I don't think we should track first and last names 
    [JsonProperty("Password")] 
    public string password { get; private set; } //will probably need to implement validation in setter so won't be able to auto-implement 
    [JsonProperty("Email")] 
    private string email { get; set; }//same with this. will need validation 
    [JsonProperty("MemberCity")] 
    private string memberCity { get; set; } 
    [JsonProperty("MemberState")] 
    private string memberState { get; set; } 
    [JsonProperty("MemberZip")] 
    private string memberZip { get; set; } 
    [JsonProperty("MemberPhone")] 
    private string memberPhone { get; set; }//should also be optional 
    [JsonProperty("FaveTeamID")] 
    private int faveTeamID { get; set; } 

    public static List<Members> MembersList = new List<Members>(); 

    public Members(string first, string last, string user, string pass, string email, string city, string state, string zip, string phone, int team) 
    { 
     //memberID = id; 
     firstName = first; 
     lastName = last; 
     userName = user; 
     password = pass; 
     this.email = email; 
     memberCity = city; 
     memberState = state; 
     memberZip = zip; 
     memberPhone = phone; 
     faveTeamID = team; 
    } 

    public override string ToString() 
    { 
     return "Member: " + userName + " in " + memberCity; 
    } 

    public bool compareUserAndPassword(string currUser, string currPass) 
    { 
     if (currUser.Equals(userName) && currPass.Equals(password)) 
     { 
      return true; 
     } 
     else 
     { 
      return false; 
     } 
    } 
} 

Наконец, вот мой серверный объект данных:

public partial class Member 
{ 
    public int MemberID { get; set; } 

    [Required] 
    [StringLength(255)] 
    public string FirstName { get; set; } 

    [Required] 
    [StringLength(255)] 
    public string LastName { get; set; } 

    [Required] 
    [StringLength(50)] 
    public string UserName { get; set; } 

    [Required] 
    [StringLength(32)] 
    public string Password { get; set; } 

    [Required] 
    [StringLength(50)] 
    public string Email { get; set; } 

    [Required] 
    [StringLength(50)] 
    public string City { get; set; } 

    [Required] 
    [StringLength(30)] 
    public string State { get; set; } 

    [Required] 
    [StringLength(255)] 
    public string Zip { get; set; } 

    [Required] 
    [StringLength(255)] 
    public string Phone { get; set; } 

    public int FavTeamID { get; set; } 
} 

Я знаю, что это много кода, но я бы предпочел разместить слишком много, чем слишком мало. Один из моих соображений заключался в том, чтобы каким-то образом добавить значение MemberID в объект httpClient и передать его как параметр на другие страницы, но я не уверен, что это возможно. Как я могу получить значение MemberID для определенного члена, если это значение сохраняется только в объекте данных на стороне сервера, но не в клиентской модели? Я открыт для разных подходов, если есть более простой способ сделать это. Спасибо заранее за вашу помощь.

UPDATE

Мой вопрос, как представляется, происходящим из моего метода GetMemberIDByName в моем контроллере. Когда я отлаживал его, у меня появилось следующее сообщение об ошибке:

Невозможно вызвать метод действия 'System.Threading.Tasks.Task`1 [T] GetMemberIDByNameT' на контроллере 'WorkVersionGetItDone.Controllers.MembersController', потому что метод действия является общий метод.

ответ

1

Я уверен, что ваш метод должен выглядеть следующим образом:

public async Task<IHttpActionResult> GetMemberIDByName(string MemberStr) 
{ 
    var member = await db.Members.Where(x => x.UserName == MemberStr).ToListAsync(); 
    if (member == null) 
    { 
     return NotFound(); 
    } 
    return Ok(member[0].MemberID); 
} 

Вызывающий будет либо получить 404 (NotFound()) или 200 с полезной нагрузкой MemberID и вы можете обработать соответствующим образом ,

HttpResponseMessage memberResponse = await client.GetAsync("api/Members?MemberStr=" + currUser); 

if(memberResponse.StatusCode == HttpStatusCode.OK) 
{ 
    // got the memberId... 
    var memberId = Convert.ToInt32(memberResponse.Content.ReadAsStringAsync().Result); 
} 
else if(memberResponse.StatusCode == HttpStatusCode.NotFound) 
{ 
    // member not found... 
} 
+0

Спасибо. Это очень похоже на то, что я придумал. Знаете ли вы, как я могу получить эту ценность в моем клиентском коде? Теперь мой сервер возвращается к правильному значению(), но мне трудно получить это значение в моем клиентском коде. Есть идеи? – jeffkempf

+0

См. Обновления, которые я сделал для ответа. Я должен отметить, что код 'GetMemberIDByName' довольно хрупкий, поскольку он предполагает, что вы получите 0 или 1 членов для' MemberStr'.Если вам удастся получить> 1, вы просто случайно захватите первый. –

+0

Спасибо. Сначала я этого не видел. Я использовал код, который вы упомянули, но он никогда не попадает в OK или NotFound. Я импортировал System.Net для HttpStatusCode. Я также попытался импортировать Windows.Net.Http, но это вызвало еще больше проблем. Есть предположения? – jeffkempf