【问题标题】:Invalid Request when calling my Web API调用我的 Web API 时请求无效
【发布时间】:2015-11-09 15:14:18
【问题描述】:

我正在尝试从 c# 客户端应用程序调用我的 web api

这是我的 API 控制器服务器代码:

    public IEnumerable<Services.Customer> Get(Guid CompanyRef)
    {
        return customerRepository.Get(CompanyRef);
    }

    public Models.CustomerAddress Add(Guid CompanyRef, string ContactNo, Guid CustomerRef, string DOE, string Email, string FName, string SName,
        Guid? addressRef, string add1, string add2, string add3, string town, string county, string pCode, string country)
    {
        var res= customerRepository.Add(CompanyRef, ContactNo, CustomerRef, DOE, Email, FName, SName,
             addressRef,  add1,  add2,  add3,  town,  county,  pCode,  country);
        return new Models.CustomerAddress {
            AddressRef =res.AddressRef,
            CustomerRef =res.CustomerRef,
            CustomerExists=  (res.CustomerRef==CustomerRef)? true : false
        };
    }

通过直接在浏览器中输入 uri,我可以对此进行测试。

http://myipaddress/api/Customer?CompanyRef=00000000-0000-0000-0000-00000000000&ContactNo=contactno2&CustomerRef=00000000-0000-0000-0000-000000000000&DOE=doe2&Email=email2&FName=fname2&SName=sname2&AddressRef=00000000-0000-0000-0000-000000000000&Add1=add1&Add2=add2&Add3=add3&Town=town&County=county&PCode=pcode&Country=country

但我得到了这样的回应:

Error>
<Message>The request is invalid.</Message>
</Error>

我看不出我做错了什么?

谢谢

附加信息

这是我从 C# 桌面客户端调用它的代码:

using (var client = new HttpClient())
{
    client.BaseAddress = new Uri(Shared.URL);
    client.DefaultRequestHeaders.Accept.Clear();
    client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(Shared.HeaderType));
    var response = client.PostAsync(route + "?" +
        GeneralTags.COMPANY_REF + "=" + ApplicationObject.CompanyRef + "&" +
        GeneralTags.CONTACT_NO + "=" + customer.ContactNo + "&" +
        GeneralTags.CUSTOMER_REF + "=" + customerLookUpResult.CustomerRef + "&" +
        GeneralTags.DOE + "=" + customer.DOE + "&" +
        GeneralTags.EMAIL + "=" + customer.Email + "&" +
        GeneralTags.FNAME + "=" + customer.FName + "&" +
        GeneralTags.SNAME + "=" + customer.SName + "&" +
        GeneralTags.ADDRESS_REF + "=" + addressLookUpResult.AddressRef +
        GeneralTags.ADD1 + "=" + customer.Add1 + "&" +
        GeneralTags.ADD2 + "=" + customer.Add2 + "&" +
        GeneralTags.ADD3 + "=" + customer.Add3 + "&" +
        GeneralTags.TOWN + "=" + customer.Town + "&" +
        GeneralTags.COUNTY + "=" + customer.County + "&" +
        GeneralTags.PCODE + "=" + customer.PCode + "&" +
        GeneralTags.COUNTRY + "=" + customer.Country
       , null).Result;

    response.EnsureSuccessStatusCode();
    string json = await response.Content.ReadAsStringAsync();
    var objs = JArray.Parse(json);
    return JsonConvert.DeserializeObject<Model.CustomerAddress>(response.Content.ReadAsStringAsync().Result);
}

当我使用它时,它会进入我的:

public IEnumerable<Services.Customer> Get(Guid CompanyRef)

修改后的 URI:L

这是我的 uri:

"http://uri/api/Customer/Add?CompanyRef=00000000-0000-0000-0000-000000000000&ContactNo=contactno2&CustomerRef=00000000-0000-0000-0000-000000000000&DOE=doe2&Email=email2&FName=fname2&SName=sname2&AddressRef=00000000-0000-0000-0000-000000000000Add1=add1&Add2=add2&Add3=add3&Town=town&County=county&PCode=pcode&Country=country"

【问题讨论】:

  • 你的控制器叫什么名字?
  • 我们调试,是不是碰到控制器了?
  • @PraveenPaulose 它是:公共类 CustomerController : ApiController
  • @BillMartin 不是来自浏览器,但如果我从 c# 桌面创建一个 httpclient,它会出于某种原因进入公共 IEnumerable Get(Guid CompanyRef)
  • 在您的PostAsync 调用中,您将传递一个HttpContent 实例,而不是传递null,看看这个其他问题:stackoverflow.com/questions/24109246/…

标签: c# asp.net-web-api


【解决方案1】:

您的签名与控制器不匹配。模型绑定器需要一个 GUID,但您传递的更多。

改为传递这个: http://myipaddress/api/Customer?CompanyRef=(enter 此处为指导)

【讨论】:

  • 您好比尔,感谢您的回答。我已经更新了我的答案。我传入的变量是 GUID。也许通过浏览器进行测试并不是一个好主意 :)
  • 应该在浏览器中工作。我推荐 Fiddler 或 Postman。非常适合 webapi 工作。
  • 嗨,比尔。抱歉,如果这是一个愚蠢的问题(看了这个问题太久了,而且迟到了一杯咖啡),但是路由的东西肯定看起来更干净......我只是使用(在这种情况下)[Route("Customer/{Add}/ {CustomerRef}/{ContactNo}/etc 等等等等")]?谢谢
  • 它将是 [Route("Customer/Add/{CustomerRef}/{ContactNo}/etc etc etc")]。那么你的网址就是service/customer/Add/(customerRef)/(CustomerNo)
  • 如果你要添加,你真的应该使用 POST。然后调用 service/customer/Add 并在 body 中发送数据。创建一个与您的数据匹配的模型并将其用作您的参数:Add([FromBody] ModelWithData model)
【解决方案2】:

在您的控制器中,您有一个名为 Add 的方法。此方法未使用 [HttpGet] 修饰。看起来它是一个 POST 方法。不能以这种方式从浏览器 url 调用 POST 方法。

如果您希望它被调用,请将属性添加到 Add 操作中

[HttpGet]
public Models.CustomerAddress Add(Guid CompanyRef, string ContactNo, Guid CustomerRef, string DOE, string Email, string FName, string SName,
    Guid? addressRef, string add1, string add2, string add3, string town, string county, string pCode, string country)
{
    var res= customerRepository.Add(CompanyRef, ContactNo, CustomerRef, DOE, Email, FName, SName,
         addressRef,  add1,  add2,  add3,  town,  county,  pCode,  country);
    return new Models.CustomerAddress {
        AddressRef =res.AddressRef,
        CustomerRef =res.CustomerRef,
        CustomerExists=  (res.CustomerRef==CustomerRef)? true : false
    };
}

完成此操作后,您需要使用 URL 调用它并指定添加操作

http://myipaddress/api/Customer/Add?CompanyRef=00000000-0000-0000-0000-00000000000&ContactNo=contactno2&CustomerRef=00000000-0000-0000-0000-000000000000&DOE=doe2&Email=email2&FName=fname2&SName=sname2&AddressRef=00000000-0000-0000-0000-000000000000&Add1=add1&Add2=add2&Add3=add3&Town=town&County=county&PCode=pcode&Country=country

如果你需要它是一个 POST 方法,你可以使用 POSTMAN 来测试你的 url。

【讨论】:

  • 如果你添加,你不想用HttpPost装饰吗?
  • @BillMartin 是的,应该。这就是为什么答案的最后一行。 Andrew 试图通过浏览器对其进行测试,这就是建议的原因。
  • @BillMartin 解释了为什么这些东西挂了很久 :)
  • @PraveenPaulose 我按照你的建议做了,即 [httpPost] 但它仍然调用我的“获取”api? :(
  • @AndrewSimpson 我建议使用属性路由。确保调用正确的方法:asp.net/web-api/overview/web-api-routing-and-actions/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-12-26
  • 1970-01-01
  • 2013-08-20
  • 2017-09-17
  • 2015-04-29
  • 2019-08-02
  • 1970-01-01
相关资源
最近更新 更多