将可选参数传递给 ASP.NET API 的 GET 方法

Posted

技术标签:

【中文标题】将可选参数传递给 ASP.NET API 的 GET 方法【英文标题】:passing optional parameter to GET method of ASP.NET API 【发布时间】:2021-06-30 14:25:51 【问题描述】:

我正在学习 ASP.NET API。在控制器中,我有 GET Verb 的这个方法

 public HttpResponseMessage Get(string gender="All")
    
        using (EmployeeDBEntities entities = new EmployeeDBEntities())
        
            switch(gender.ToLower())
                
                case "all":
                    return Request.CreateResponse(HttpStatusCode.OK, entities.Employees.ToList());
                    
                case "female":
                case "male":
                    return Request.CreateResponse(HttpStatusCode.OK,
                        entities.Employees.Where(x=>x.Gender==gender).ToList());
                default:
                    return Request.CreateErrorResponse(HttpStatusCode.NotFound, " value of gender is wrong");
            ;
        
    

当我浏览到 http://localhost:61491/api/Employees/gender=female 时,我收到以下错误:

 <Error>
 <Message>The request is invalid.</Message>
 <MessageDetail>The parameters dictionary contains a null entry for parameter 'id' of non-nullable type 'System.Int32' for method 'System.Net.Http.HttpResponseMessage Get(Int32)' in 'EmployeeService.Controllers.EmployeesController'. An optional parameter must be a reference type, a nullable type, or be declared as an optional parameter.</MessageDetail>
 </Error>

/**编辑 > 这是API Service的web.config文件

   <?xml version="1.0" encoding="utf-8"?>
  
   <configuration>

    <connectionStrings>
    <add name="EmployeeDBEntities" connectionString="metadata=res://*/EmployeeDataModel.csdl|res://*/EmployeeDataModel.ssdl|res://*/EmployeeDataModel.msl;provider=System.Data.SqlClient;provider connection string=&quot;data source=localhost;initial catalog=EmployeeDB;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework&quot;" providerName="System.Data.EntityClient" />
    </connectionStrings>

 <appSettings>
   <add key="webpages:Version" value="3.0.0.0" />
   <add key="webpages:Enabled" value="false" />
   <add key="ClientValidationEnabled" value="true" />
   <add key="UnobtrusivejavascriptEnabled" value="true" />
 </appSettings>
 <system.web>
      <compilation debug="true" targetFramework="4.5.2" />
      <httpRuntime targetFramework="4.5.2" />
       <httpModules>
         <add name="ApplicationInsightsWebTracking" type="Microsoft.ApplicationInsights.Web.ApplicationInsightsHttpModule, Microsoft.AI.Web" />
      </httpModules>
   </system.web>
   <system.webServer>
   <handlers>
        <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
        <remove name="OPTIONSVerbHandler" />
        <remove name="TRACEVerbHandler" />
        <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
       </handlers>
       <validation validateIntegratedModeConfiguration="false" />
       <modules>
       <remove name="ApplicationInsightsWebTracking" />
       <add name="ApplicationInsightsWebTracking" type="Microsoft.ApplicationInsights.Web.ApplicationInsightsHttpModule, Microsoft.AI.Web" preCondition="managedHandler" />
      </modules>
      </system.webServer>
     <runtime>
      <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
       <dependentAssembly>
    <assemblyIdentity name="Newtonsoft.Json" culture="neutral" publicKeyToken="30ad4fe6b2a6aeed" />
    <bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
  </dependentAssembly>
  <dependentAssembly>
    <assemblyIdentity name="System.Web.Optimization" publicKeyToken="31bf3856ad364e35" />
    <bindingRedirect oldVersion="1.0.0.0-1.1.0.0" newVersion="1.1.0.0" />
  </dependentAssembly>
  <dependentAssembly>
    <assemblyIdentity name="WebGrease" publicKeyToken="31bf3856ad364e35" />
    <bindingRedirect oldVersion="0.0.0.0-1.5.2.14234" newVersion="1.5.2.14234" />
  </dependentAssembly>
  <dependentAssembly>
    <assemblyIdentity name="System.Web.Helpers" publicKeyToken="31bf3856ad364e35" />
    <bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
  </dependentAssembly>
  <dependentAssembly>
    <assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35" />
    <bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
  </dependentAssembly>
  <dependentAssembly>
    <assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
    <bindingRedirect oldVersion="1.0.0.0-5.2.3.0" newVersion="5.2.3.0" />
  </dependentAssembly>
   </assemblyBinding>
   </runtime>
  <system.codedom>
<compilers>
  <compiler language="c#;cs;csharp" extension=".cs" type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.CSharpCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=1.0.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" warningLevel="4" compilerOptions="/langversion:6 /nowarn:1659;1699;1701" />
  <compiler language="vb;vbs;visualbasic;vbscript" extension=".vb" type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.VBCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=1.0.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" warningLevel="4" compilerOptions="/langversion:14 /nowarn:41008 /define:_MYTYPE=\&quot;Web\&quot; /optionInfer+" />
    </compilers>
  </system.codedom>
   </configuration>

可能是什么原因?

【问题讨论】:

能否请您发布您的启动文件或 webconfig 文件? 可能;你做你的请求错误的路线。第一步,确保您的请求符合您的方法。 @Sergey:我在上面添加了它 谢谢。很抱歉,但我需要查看端点配置文件。你有路由配置文件吗? 【参考方案1】:

您的代码很好。是你的网址是错误的:

http://localhost:61491/api/Employees/gender=female

我会给出一个快速的解决方案,然后给出更多细节,如果你正在学习 API,我强烈建议你阅读。您的网址应该是:

http://localhost:61491/api/Employees?gender=female

使用 C# API,您可以通过 3 种可能的方式发送数据:

查询参数 路由参数 在请求正文中

查询参数

这是默认类型。这意味着如果您不指定方法,它将始终假定您的输入是查询参数。不仅如此,查询参数默认是可选的并且可以为空。如果您为查询参数输入 null,它将被分配 default 值。

可以通过? 标记在URL 中标识查询参数。之后的任何数据都是查询参数,可以按任何顺序分配。例如:

 MyUrl?Name=Jhon&Age=20&Sex=M

&amp; 表明这是一个拆分。上面的数据会映射到端点:

 public HttpResponseMessage Get(string name, string sex, int age)

参数可以按任何顺序排列。它会正确映射。

路由参数

这些是直接从路由获取的查询。调整您的请求,它将如下所示:

 /api/Employees/gender/female

端点本身如下所示:

[HttpGet("gender/sex")]
public HttpResponseMessage Get([FromRoute] string sex) ...

你不能默认使用路由参数,你需要指定它是一个路由参数:

将参数放在路径中的终点在括号 用 [FromRoute] 属性表明 api 应该使用路由来获取属性。默认情况下,路由是必需的。您不能将其用作可选参数。

车身参数

这只是您将请求的正文作为参数读取。当您发布或放置数据时很好 没有太多细节,但看起来如下:

 public HttpResponseMessage Get([FromBody] Model data) ...

请务必注意,[FromBody] 参数与 Get 请求不兼容。


请求类型

您需要知道的一件重要事情是request types。有很多,但默认情况下它总是一个 Get 请求。

您的代码:

public HttpResponseMessage Get(...) ...

不是获取请求,因为您写了GET。您可以随意命名该请求,例如:

public HttpResponseMessage ThisIsMyPostRequest(...) ...

但您仍然可以使用GET 请求检索数据。指定是什么类型的请求,可以加一个http属性标签:

[HttpGet]
public HttpResponseMessage MyGetFuncName()...

[HttpPost]
public HttpResponseMessage MyPostFuncName()...

[HttpPut]
public HttpResponseMessage MyPutFuncName()...

[HttpDelete]
public HttpResponseMessage MyDeleteFuncName()...

[HttpOptions]
public HttpResponseMessage MyOptionsFuncName()...

[HttpHead]
public HttpResponseMessage MyHeadFuncName()...
...

真的就这么简单。不同的HttpRequest 大多工作相同。但是有一些不同之处。最常用的是GETPOSTPUTDELETE

当你想使用相同的路线但不同的功能时,这变得很有用。例如GETDELETE 可以在同一条路线上:

/api/Employees/Byname?name=Jhon

但根据请求类型将返回用户或删除它。


自定义路线

您需要知道的最后一件重要且强大的事情是Routes。如果我在您的控制器页面顶部没有弄错,您有以下属性:

  [Route("[controller]")]

  [Route("api/[controller]")]

该函数所做的是它和控制器上所有请求的前缀。现在您实际上也可以将其添加到各个函数中。这意味着如果您在单个页面上有多个 GET 函数,这对于保持其正常工作至关重要。示例:

     [Route("ByGenders")]
     public HttpResponseMessage Get(string gender="All")

      /api/Employees/ByGenders?gender=female

     ...

     [Route("Byname")]
     public HttpResponseMessage Get(string name)

     /api/Employees/Byname?name=Jhon

但它实际上可以与 HttpRequest 属性结合使用。意思是上面将等同于:

     [HttpGet("ByGenders")]
     public HttpResponseMessage Get(string gender="All")

     [HttpGet("Byname")]
     public HttpResponseMessage Get(string name)

当然,您可以将以上所有内容放在一个包含大量细节的独特端点中。下面是一个小例子:

    [HttpGet("GetWithParams/requiredInput")]
    public IActionResult GetWithParams(
        [FromRoute] string requiredInput,
        [FromQuery] string optionalInput)
    
        return Ok($"Required Input: requiredInput | Optional Input: optionalInput");
    

或者

    [HttpPost("UserId/id")]
    public IActionResult SubmitApplication(
        [FromRoute] int id,
        [FromBody] UserApplicationModel application)
    

        return BadRequest();
    

【讨论】:

以上是关于将可选参数传递给 ASP.NET API 的 GET 方法的主要内容,如果未能解决你的问题,请参考以下文章

如何将可选参数传递给 C++ 中的方法?

是否有必要在将可选参数传递给另一个可选参数之前检查它?

将可选路径参数传递给 ant

如何将可选参数传递给typescript中的回调函数

当我将可选参数传递给视图时,为啥我的 CSS 静态文件在 Django 中不起作用?

如何使用 vba 将参数传递给 asp.net web api?