Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/284.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
C# 如何告诉asp.NETMVC和api使用私有setter反序列化模型?_C#_Asp.net Mvc_Asp.net Web Api - Fatal编程技术网

C# 如何告诉asp.NETMVC和api使用私有setter反序列化模型?

C# 如何告诉asp.NETMVC和api使用私有setter反序列化模型?,c#,asp.net-mvc,asp.net-web-api,C#,Asp.net Mvc,Asp.net Web Api,比如说我得到了 public class TestModel { public int a { get; set; } public int b { get; private set; } } 及 然后导航到 /Test?a=1&b=2 将仅设置属性a。由于私有setter,属性b被忽略 有没有办法告诉序列化程序使用私有setter反序列化属性?(MVC和web api) 这样做有什么坏处吗?正如一条评论中已经提到的,您不应该对私有财产进行反序列化(为什么它首先是私有

比如说我得到了

public class TestModel
{
    public int a { get; set; }
    public int b { get; private set; }
}

然后导航到

/Test?a=1&b=2
将仅设置属性a。由于私有setter,属性b被忽略

有没有办法告诉序列化程序使用私有setter反序列化属性?(MVC和web api)


这样做有什么坏处吗?

正如一条评论中已经提到的,您不应该对私有财产进行反序列化(为什么它首先是私有的?)。一种方法是使用包装器属性:

public class TestModel
{
    public int a { get; set; }
    public int b { get; private set; }

    public int bSet 
    {
        set { b = value; }
    }
}
但必须更改URL:

/Test?a=1&bSet=2

虽然理论上可以编写自定义转换器,利用反射映射到私有setter属性,但不建议这样做

相反,优先考虑通过尊重属性访问器级别来保持清晰、一致的API边界


实现这一点的一种方法是利用不同的模型来实现不同的目标。使用用作反序列化模型的所有公共setter创建一个简单的POCO。将该模型映射到整个应用程序中使用的具有私有setter的第二个模型。这允许您在应用程序中实现适当的关注点分离。

默认情况下,ASP.Net MVC使用,而Web API使用NewtonSoft JSON.Net。因此,除非向MVC添加自定义代码以更改默认序列化程序,否则无论如何都无法使两者保持一致。也就是说,您仍然存在序列化到私有setter的问题,这通常是一种反模式。能做到吗?当然应该是吗?可能不会。简而言之,您不能反序列化为私有setter。您可以忽略该属性,并在事后以其他方式对其进行设置,但显然,如果setter不是公共的,则反序列化程序之类的东西无法对其进行设置。访问器级别专门用于提供封装和清除API边界。如果你试图绕过这些界限,你就违反了这些界限。私有setter不应该从公共上下文中设置,这正是反序列化的含义。所以,是的,你可以让它工作,但它违反了代码本身的内在契约。@DavidL:好吧,也许最好说在正常情况下,你不能反序列化为私有setter。采取这种大刀阔斧的步骤试图绕过访问器级别,这就回避了拥有访问级别的问题。要么它应该是公共的,要么它是私人的,绕开它会破坏你的应用程序。@ChrisPratt我100%同意(这就是为什么我没有发布一个答案显示这样的事情):)。我只想指出这确实是可能的。
/Test?a=1&bSet=2