类属性中的动态类型

时间:2019-02-05 07:18:42

标签: c# generic-list

在GetInfo方法中,以JSON格式返回结果,如下所示:

public function redirectToProvider()
{
   return Socialite::driver('google')->with(["prompt" => "select_account"])->redirect();
}

我可以将结果值反序列化为

<div class="col-xs-12 col-sm-12 col-md-9 col-lg-9">
   <div class="container-fluid p-0">
      <div  style="width:100%; overflow-x:auto; white-space: nowrap;">
         <form id="TICKETSALE_ORDERTICKETSELECTSEATFORM" action="TICKETSALE_ORDERTICKETSELECTSEATFORM.php" method="POST">
            <div class="row row-eq-height mb-4 px-2 py-2" style="background-color:purple; height:40px;">
               <div class="col-sm-12" align="center">
                  <div class="row">
                     <div class="col-sm-12" >
                        <label class="text-center " style="color:white; font-weight:900;">SCREEN</label>
                     </div>
                  </div>
               </div>
            </div>
            <?php
                for($a=1; $a<=$row_Q1[0]['ROW']; $a++){
                    //row
            ?>
               <div class="row row-eq-height ">
            <?php
               for($b=1; $b<=$row_Q1[0]["COL"]; $b++){
                  //col
            ?>
               <div class="col">
            <?php
               $RowKeyExist = checkIfKeyExist($row_Q2, $a, $b);
                  if($RowKeyExist!== false){
            ?>
                     <div id=<?=$a.",".$b?>>
                        <div class="form-check pl-0">
                           <label class="fas fa-chair SEATIMAGE">
                           <?php
                              if($row_Q2[$RowKeyExist]["TICKETCODE"]=='1'){ //"1" is booked
                                 echo "style='font-size:25; font-family: Font Awesome\ 5 Free; display: inline-block; content: \f630;  font-weight: 900;  color:grey;'";
                              }elseif($row_Q2[$RowKeyExist]["TICKETCODE"]=='2'){ //"2" is bought
                                 echo "style='font-size:25; font-family: Font Awesome\ 5 Free; display: inline-block; content: \f630;  font-weight: 900;  color:red;'";
                              }elseif($row_Q2[$RowKeyExist]["TICKETCODE"]=='0'){ //"0" is temp bought in db and not current user
                                 echo "style='font-size:25; font-family: Font Awesome\ 5 Free; display: inline-block; content: \f630;  font-weight: 900;  color:grey;'";
                              }elseif($row_Q2[$RowKeyExist]["TICKETCODE"]==null){ //"null" is vacant
                                 echo "style='font-size:25; font-family: Font Awesome\ 5 Free; display: inline-block; content: \f630;  font-weight: 900;  color:green;'";
                              }
                           ?>
                           </label>
                           <div>
                              <label><?=$row_Q2[$RowKeyExist]["SEATLABEL"];?></label>
                           </div>
                        </div>
                     </div>
                  <?php
                     }else{
                  ?>
                     <div class="d-none">
                        <label class="fas fa-chair SEATIMAGE" style="font-size:25; font-family: Font Awesome\ 5 Free; display: inline-block; content: \f630;  font-weight: 900;  color:purple;"></label>
                        <div>
                           <label>NONE</label>
                        </div>
                     </div>
                  <?php
                     }
                  ?>
                  </div>
               <?php
                  }
               ?>
               </div>
            <?php
               }
            ?>
         </form>
      </div>
   </div>
</div>

在GetList方法结果JSON中:

"Result": {
    "Id": 11975,
    "Email": null,
    "CellPhone": "123456789",
    "FirstName": "John",
    "LastName": "Rock",
    "Avatar": null,
    "Address": null,
},
"StatusCode": 200,
"Message": "success",
"Version": "API V1.1"

如何在Response类中为任何类型的类创建动态Result属性?

2 个答案:

答案 0 :(得分:1)

有一个关键字动态,您可以将其用作“结果”字段的类型。虽然看起来您的两个响应应该是相当独立的类,但它们可能从一个包含 StatusCode 消息版本< / strong>。在继承的类中,您只需添加特定类型的 Response 字段以匹配响应。

public abstract class Result
{
    public int StatusCode { get; set; }
    public string Message { get; set; }
    public string Version { get; set; }
}

public class SignInResult : Result
{
    public SignInResponse Response { get; set; }
}

public class ListResult : Result
{
    public IList<ListResponse> Response { get; set; }
}

在这种情况下,您可以看到Response字段始终存在,但类型不同,因此您可以创建Result类,如下所示:

public abstract class Result<T>
{
    public T Response { get; set; }
    public int StatusCode { get; set; }
    public string Message { get; set; }
    public string Version { get; set; }
}

然后在使用正确的类型参数反序列化时使用它。

答案 1 :(得分:0)

您可以一起利用Generic Class和JToken来从响应中获得反序列化数据

public class StandardResponse<T>
{
    public JToken Result { get; set; }
    public int StatusCode { get; set; }
    public string Message { get; set; }
    public string Version { get; set; }

    public List<T> _Result
    {
        get
        {
            if (Result.Type == JTokenType.Array)
            {
                List<T> signInResponses = new List<T>();
                signInResponses = Result.ToObject<List<T>>();
                return signInResponses;
            }
            else if (Result.Type == JTokenType.Object)
            {
                List<T> signInResponses = new List<T>();
                signInResponses.Add(Result.ToObject<T>());
                return signInResponses;
            }
            else
                return new List<T>();
        }
    }
}

在上述类中,属性Result的类型为JToken意味着可以将任何有效的json反序列化为该类型。

然后属性_Result的类型为List<T>,其中T是您要从json反序列化Result密钥数据的任何类。

如果您的Result键包含的数据类型为

  • 对象然后_Result将为您提供类型为T的单个对象的列表。
  • 先列出,然后_Result会给您列出类型为T的多个对象的列表

因此,您不再需要手动检查键Result是否包含对象或数组类型的数据。 _Result属性将为您完成此任务。

用法:

var result = JsonConvert.DeserializeObject<StandardResponse<SignInResponse>>(json);

var signInResponses = result._Result;

现在,您可以像在上面的代码中使用T一样随意使用SignInResponse类的任何类型。