Asp.net mvc 如何在.net mvc web api中修改响应

Asp.net mvc 如何在.net mvc web api中修改响应,asp.net-mvc,c#-4.0,json.net,asp.net-web-api2,Asp.net Mvc,C# 4.0,Json.net,Asp.net Web Api2,嗨,我有一个C#model班。我需要通过设置他的属性将这个类作为json响应传递。这个类的一个属性名Product具有另一个Product类的类型,当没有Product的数据时,我将所有内部属性值都设置为空,但我希望json属性为空 例如,我的班级是 public class Profile_BO { public int Id { get; set; } public string Username { get; set; } public Product prod

嗨,我有一个C#model班。我需要通过设置他的属性将这个类作为json响应传递。这个类的一个属性名Product具有另一个Product类的类型,当没有Product的数据时,我将所有内部属性值都设置为空,但我希望json属性为空

例如,我的班级是

 public class Profile_BO
{

    public int Id { get; set; }
    public string Username { get; set; }
    public Product product{ get; set; }


    public class Product
    {
        public int Id { get; set; }
        public string Type { get; set; }
    }
}
我正在从如下C#数据表初始化此类:-

       Profile_BO profile_BO = new Profile_BO();

            foreach (DataRow dr in result.Tables[0].Rows)
            {
                profile_BO.Id = Convert.ToInt32(dr[0]);
                profile_BO.Username = Convert.ToString(dr[1]);
            }

            Product product = new Product();

            foreach (DataRow dr1 in result.Tables[1].Rows)
            {
                product.Id = Convert.ToInt32(dr1[0]);
                product.Type = Convert.ToString(dr1[1]);
            }

            profile_BO.product = product;
最后,当我作为对方法的响应传递时:-

 public async Task<HttpResponseMessage> GetUserInfo(Profile_Request profile_Request)
    {
           return request.CreateResponse(HttpStatusCode.OK, profile_BO);
}
但是,当我的产品表中没有数据时,我会得到以下信息:-

{
  "Id": "1",
  "Username": "abc",
  "product": {
    "Id": 0,
    "Type": ""
  }
}
{
  "Id": "1",
  "Username": "abc",
  "product": {}
}
但是如果没有数据我希望输出如下所示:-

{
  "Id": "1",
  "Username": "abc",
  "product": {
    "Id": 0,
    "Type": ""
  }
}
{
  "Id": "1",
  "Username": "abc",
  "product": {}
}

另一个问题是:-这是从数据集绑定响应模型的正确方法吗?

您面临的问题是,您正在初始化
Product
的一个实例,而不管实际上可能根本没有产品。这将导致使用默认值初始化其属性
Int32
默认为0
System.String
作为引用类型为
null

Profile_BO profile_BO = new Profile_BO();

foreach (DataRow dr in result.Tables[0].Rows)
{
    profile_BO.Id = Convert.ToInt32(dr[0]);
    profile_BO.Username = Convert.ToString(dr[1]);
}

//I am assuming you only expect one row, since oyur model uses a single Product
//and no collection of products. No need for a loop then.
if(result.Tables[1].Rows.Count == 1) { 
    Product product = new Product();
    var dr1 = result.Tables[1].Rows[0];

    product.Id = Convert.ToInt32(dr1[0]);
    product.Type = Convert.ToString(dr1[1]);

    profile_BO.product = product;
}
这将导致返回以下JSON:

{
  "Id": "1",
  "Username": "abc",
  "product": null
}
编辑:如果您确实必须拥有
产品:{}
,则您不需要更改您的型号

public class Profile_BO
{
    public int Id { get; set; }
    public string Username { get; set; }
    public object product { get; set; }

}

public class Product
{
    public int Id { get; set; }
    public string Name { get; set; }
}
将产品声明为
对象
。由于所有类都继承自对象,因此您可以将其实例化为对象或产品,具体取决于您的情况:

if(result.Tables[1].Rows.Count == 1) { 
    Product product = new Product();
    var dr1 = result.Tables[1].Rows[0];

    product.Id = Convert.ToInt32(dr1[0]);
    product.Type = Convert.ToString(dr1[1]);

    profile_BO.product = product;
}
或:

这将导致:

{"Id":1,"Username":"Foo Bar","product":{}}

然而,我强烈建议使用第一种方法,因为这将使测试和修改更容易,因为您保留了强类型方法。

我之前的回答对您的最后一个问题没有帮助。这是我编辑过的解决方案

更好的解决方案

可能更好的解决方案是使用自定义消息处理程序

委派处理程序也可以跳过内部处理程序并直接 创建响应

自定义消息处理程序:

public class NullJsonHandler : DelegatingHandler
    {
        protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
        {

            var updatedResponse = new HttpResponseMessage(HttpStatusCode.OK)
            {
                Content = null
            };

            var response = await base.SendAsync(request, cancellationToken);

            if (response.Content == null)
            {
                response.Content = new StringContent("{}");
            }

            else if (response.Content is ObjectContent)
            {

                var contents = await response.Content.ReadAsStringAsync();

                if (contents.Contains("null"))
                {
                    contents = contents.Replace("null", "{}");
                }

                updatedResponse.Content = new StringContent(contents,Encoding.UTF8,"application/json");

            }

            var tsc = new TaskCompletionSource<HttpResponseMessage>();
            tsc.SetResult(updatedResponse);   
            return await tsc.Task;
        }
    }
现在,所有包含
null
Asp.NET Web API
响应都将替换为空的
Json
body
{}

参考文献:

public class NullJsonHandler : DelegatingHandler
    {
        protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
        {

            var updatedResponse = new HttpResponseMessage(HttpStatusCode.OK)
            {
                Content = null
            };

            var response = await base.SendAsync(request, cancellationToken);

            if (response.Content == null)
            {
                response.Content = new StringContent("{}");
            }

            else if (response.Content is ObjectContent)
            {

                var contents = await response.Content.ReadAsStringAsync();

                if (contents.Contains("null"))
                {
                    contents = contents.Replace("null", "{}");
                }

                updatedResponse.Content = new StringContent(contents,Encoding.UTF8,"application/json");

            }

            var tsc = new TaskCompletionSource<HttpResponseMessage>();
            tsc.SetResult(updatedResponse);   
            return await tsc.Task;
        }
    }


您正在初始化产品。即使未设置其值,
Id
的类型为
Int32
,其默认值为0。您应该先检查是否有产品,然后再初始化。如果我没有初始化,它会给我“产品”:null,我想要“产品”:{}我已经用一种方法更新了我的答案,以获得
product:{}
@Marco,从数据集绑定响应模型是正确的方法吗?这是一种方法。如果它对你有效,这是一个正确的方法。通常有多种解决问题的方法。你真的抄了我的答案吗?没有@Marco我是根据你的评论写答案的,但你已经在我面前发布了你的答案:)。你看,你和我之间有细微的差别
.Rows.Count>=1
。如果你仍然不开心,我会删除这个。不,保留它。在我仔细考虑之前,我正在写我的评论。SorryHi,我添加了一个更好的解决方案,使用
自定义消息处理程序
,而不是使用
新对象()项目检查中的每个位置。也许它是有用的