如何在 class 中使用隐式运算符在 web api 中传递参数 c#
How to use implicit operators in class for passing parameter in web api c#
我有 Web API,如果在 URL 查询中传递的参数之一为空,它会抛出错误。假设我无法覆盖上述验证的任何内容。
所以,我想要一个 Web API,如下所示,参数 c
是字符串,API 调用可能传递一个空字符串,它实例化参数 c
作为 null
而不是 ""
.
[Route("{id}")]
[HttpGet]
public IdDTO GetIdDetails(
int Id,
[FromUri] int a,
[FromUri] string b,
[FromUri] string c,
{
//doing something here...
}
典型的 API 调用是 localhost:3000/123?a=1&b=abc&c=
我还将 c
的数据类型更改为自定义数据类型 ReqString
([FromUri] ReqString <string> c
),如下所示
public struct ReqString<T>
{
private T _value;
public ReqString(T s)
{
_value = s;
}
public static implicit operator ReqString<T>(T s) => new ReqString<T>(s);
public static implicit operator string(ReqString<T> s)
{
if(typeof(T).Equals(typeof(string)))
{
return s._value as string == null ? "" : s._value as string;
}
else
{
return s._value.ToString();
}
}
}
现在的问题是,c
的值是 ""
。但是如果我在 API URL 查询中传递参数 c
的值,它仍然是 ""
而不是传递的值
例如:localhost:3000/123?a=1&b=abc&c=def
即 _value
仍然为 null
所以我的问题是如何使用隐式运算符实例化具有查询值的_value
?
更新
自定义数据类型在如下语句中实例化时有效,但我想在函数调用参数中获得类似结果
ReqString rStr = "testing";
根据 Michael 的评论,我查看了 ModalBinder。我能够解决我的问题。下面是我使用的示例解决方案
public class ReqStringModelBinder : IModelBinder
{
public bool BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext)
{
if (bindingContext.ModelType != typeof(ReqString))
{
return false;
}
ValueProviderResult val = bindingContext.ValueProvider.GetValue(
bindingContext.ModelName);
if (val == null)
{
return false;
}
string key = val.RawValue as string;
if (key == null)
{
bindingContext.ModelState.AddModelError(
bindingContext.ModelName, "Wrong value type");
return false;
}
ReqString result;
if (ReqString.TryParse(key, out result))
{
bindingContext.Model = result;
return true;
}
bindingContext.ModelState.AddModelError(
bindingContext.ModelName, "Cannot convert value to ReqString");
return false;
}
}
[ModelBinder(typeof(ReqStringModelBinder))]
public class ReqString
{
public string value { get; set; }
public static bool TryParse(string s, out ReqString result)
{
result = null;
result = new ReqString() { value = String.IsNullOrEmpty(s) ? "" : s };
return true;
}
public static implicit operator string(ReqString reqString) => reqString.value;
}
我有 Web API,如果在 URL 查询中传递的参数之一为空,它会抛出错误。假设我无法覆盖上述验证的任何内容。
所以,我想要一个 Web API,如下所示,参数 c
是字符串,API 调用可能传递一个空字符串,它实例化参数 c
作为 null
而不是 ""
.
[Route("{id}")]
[HttpGet]
public IdDTO GetIdDetails(
int Id,
[FromUri] int a,
[FromUri] string b,
[FromUri] string c,
{
//doing something here...
}
典型的 API 调用是 localhost:3000/123?a=1&b=abc&c=
我还将 c
的数据类型更改为自定义数据类型 ReqString
([FromUri] ReqString <string> c
),如下所示
public struct ReqString<T>
{
private T _value;
public ReqString(T s)
{
_value = s;
}
public static implicit operator ReqString<T>(T s) => new ReqString<T>(s);
public static implicit operator string(ReqString<T> s)
{
if(typeof(T).Equals(typeof(string)))
{
return s._value as string == null ? "" : s._value as string;
}
else
{
return s._value.ToString();
}
}
}
现在的问题是,c
的值是 ""
。但是如果我在 API URL 查询中传递参数 c
的值,它仍然是 ""
而不是传递的值
例如:localhost:3000/123?a=1&b=abc&c=def
即 _value
仍然为 null
所以我的问题是如何使用隐式运算符实例化具有查询值的_value
?
更新
自定义数据类型在如下语句中实例化时有效,但我想在函数调用参数中获得类似结果
ReqString rStr = "testing";
根据 Michael 的评论,我查看了 ModalBinder。我能够解决我的问题。下面是我使用的示例解决方案
public class ReqStringModelBinder : IModelBinder
{
public bool BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext)
{
if (bindingContext.ModelType != typeof(ReqString))
{
return false;
}
ValueProviderResult val = bindingContext.ValueProvider.GetValue(
bindingContext.ModelName);
if (val == null)
{
return false;
}
string key = val.RawValue as string;
if (key == null)
{
bindingContext.ModelState.AddModelError(
bindingContext.ModelName, "Wrong value type");
return false;
}
ReqString result;
if (ReqString.TryParse(key, out result))
{
bindingContext.Model = result;
return true;
}
bindingContext.ModelState.AddModelError(
bindingContext.ModelName, "Cannot convert value to ReqString");
return false;
}
}
[ModelBinder(typeof(ReqStringModelBinder))]
public class ReqString
{
public string value { get; set; }
public static bool TryParse(string s, out ReqString result)
{
result = null;
result = new ReqString() { value = String.IsNullOrEmpty(s) ? "" : s };
return true;
}
public static implicit operator string(ReqString reqString) => reqString.value;
}