Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/visual-studio-2012/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Asp.net web api 在WebAPI中,当一个方法包含可为null的值类型作为参数时,如何重载Get_Asp.net Web Api_Visual Studio 2012 - Fatal编程技术网

Asp.net web api 在WebAPI中,当一个方法包含可为null的值类型作为参数时,如何重载Get

Asp.net web api 在WebAPI中,当一个方法包含可为null的值类型作为参数时,如何重载Get,asp.net-web-api,visual-studio-2012,Asp.net Web Api,Visual Studio 2012,更新 我最初的假设是可选参数是问题的原因。这似乎是不正确的。相反,当其中一个方法包含某些参数的可空值类型(例如int?)时,多个操作方法似乎存在问题 我使用的是Visual Studio 2012 RC,我刚刚开始使用Web API。我遇到了一个问题,出现了错误“在与请求匹配的控制器“条”上找不到任何操作” 我有一个酒吧控制器。它有一个接受可选参数的Get()方法 public IEnumerable<string> Get(string h, string w = "default

更新

我最初的假设是可选参数是问题的原因。这似乎是不正确的。相反,当其中一个方法包含某些参数的可空值类型(例如int?)时,多个操作方法似乎存在问题

我使用的是Visual Studio 2012 RC,我刚刚开始使用Web API。我遇到了一个问题,出现了错误“在与请求匹配的控制器“条”上找不到任何操作”

我有一个酒吧控制器。它有一个接受可选参数的Get()方法

public IEnumerable<string> Get(string h, string w = "defaultWorld", int? z=null)
{
    if (z != 0)
        return new string[] { h, w, "this is z: " + z.ToString() };
    else
       return new string[] { h, w };
}
我再次测试URL。这次/api/bar?h=hello&w=world和api/bar?h=hello失败。错误消息是“在控制器“栏”上未找到与请求匹配的操作。”

出于某种原因,这两种方法不能很好地结合在一起。如果我删除
Get(int-id)
,它就会工作。如果我改变int?将z转换为字符串z,然后它就可以工作了(,但是它需要转换动作方法中的对象!)

为什么WebAPI会这样做?这是一个bug还是出于设计


非常感谢。

您可以通过在路由中添加操作参数来重载WEB API控制器方法

 routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{action}/{id}",
            defaults: new {action = "Get", id = RouteParameter.Optional }
        );
一旦你在你的路线上做了这个改变,你就可以调用你的方法,比如

/api/bars/get?id=1
/api/bars/get?h=hello&w=world&z=15
希望这有帮助


Omar

我还没有找到这个问题的真正答案(为什么Web API会这样做),但我有一个解决方法,允许重载Get()。诀窍是将参数值包装到对象中

public class Foo
{
    public string H { get; set; }
    public string W { get; set; }
    public int? Z { get; set; }
}
并将“条形图”控制器修改为

public IEnumerable<string> Get([FromUri] Foo foo)
{
    if (foo.Z.HasValue)
        return new string[] { foo.H, foo.W, "this is z: " + foo.Z.ToString() };
    else
        return new string[] { foo.H, foo.W, "z does not have a value" };
}
public IEnumerable Get([FromUri]Foo-Foo)
{
如果(foo.Z.HasValue)
返回新字符串[]{foo.H,foo.W,“这是z:+foo.z.ToString();
其他的
返回新字符串[]{foo.H,foo.W,“z没有值”};
}
[FromUri]
是必需的,因为默认情况下,WebAPI不使用URI参数来形成“复杂”对象。一般认为,复杂对象来自
操作,而不是GET请求


我仍将继续检查Web API为何会以这种方式运行,以及这是否真的是一个bug或预期的行为。

问题已解决,但仍留下了一个额外的问题。问题似乎是重载的操作方法在可选参数方面存在问题

所以新的问题是为什么会这样,但我将把这留给比我级别低的人;)

但这是个好消息。我不喜欢你报告的问题,走复杂类型的路线,虽然很高兴知道,只是一个jerry rig修复,会反映出Web Api中的某些东西是如何工作的。所以好消息是,如果你有这个问题,只要去掉可选的参数就可以解决,好的ol’重载路由。好消息是,这绝不是一个jerry rig修复,只是让您失去了一点可选参数便利性:

公共类BarsController:ApicController
{
公共字符串Get(int-id)
{
返回“值”;
}
公共IEnumerable Get(字符串h)
{
返回Get(h,null,null);
}
公共IEnumerable Get(字符串h、字符串w)
{
返回Get(h,w,null);
}
公共IEnumerable Get(字符串h、字符串w、int?z)
{
如果(z!=0)
返回新字符串[]{h,w,“这是z:+z.ToString()};
其他的
返回新字符串[]{h,w};
}
}

干杯

不幸的是,这不起作用。我已经有了路径集。这是一个很好的解决方案,适用于少量变量。当有多个参数是可选的时,重载会成为一个真正的难题。我面临的特殊工作问题是使用一组更大的变量来过滤返回的数据。在这些情况下,创建一个自定义的Filter()或Options()类来处理所有传入的参数更有意义。顺便提一下,您可以编辑第三个方法以使用int z,而不是int?z、 @John“如果z为空会发生什么?”问得好!我也这么想,但当时只是复制原始代码,因为这不是问题所在。所以应该检查null:if(z!=null&&z!=0)。更新:??嗯,约翰,刚刚意识到你是最初的作者。。。那是你自己的代码伙伴@不过,John提到了主要内容,嘿,说得好,简单地用自定义类型将其包装起来确实是有好处的。然而,我回答的要点只是指出问题所在,即WebAPI(或ASP.NET)没有正确地处理重载方法。是虫子吗?我不知道,但是如果可以修复的话那就太好了。顺便说一句,对于POST和PUT,如果您正在进行表单提交并且变量包含在请求体中(默认),那么您必须在Web API中使用自定义对象,因为Web API只能处理来自请求体的一个变量。因此,至少对我来说,在WebAPI中,使用自定义对象似乎更为规范,而不是例外。
public IEnumerable<string> Get([FromUri] Foo foo)
{
    if (foo.Z.HasValue)
        return new string[] { foo.H, foo.W, "this is z: " + foo.Z.ToString() };
    else
        return new string[] { foo.H, foo.W, "z does not have a value" };
}