0

我已经定义了这样一个函数:

public static void WriteResponse(ref HttpContext ctx, object sender, Type typeName)
{
    var model = sender as typeName; // it's an error-line, becase of `as typeName`
    var jsonObject = new JavaScriptSerializer().Serialize(model);
    ctx.Response.AddHeader("Access-Control-Allow-Origin", "*");
    ctx.Response.ContentType = "Content-type: application/json";
    ctx.Response.ContentEncoding = Encoding.UTF8;
    ctx.Response.Write(jsonObject);
}

如您所见,它甚至无法编译,因为以下行:

var model = sender as typeName;

我从那个调用这个函数:

internal void GetShortInfo(ref HttpContext ctx, ref Shapefile shapefile)
{
    var model = new Models.SfShortInfo()
    {
        Count = shapefile.Count,
        Type = shapefile.Type.ToString()
    };

    ShapefileService.WriteResponse(ref ctx, (object)model, model.GetType());
}

还有这样的电话:

ShapefileService.WriteResponse(ref ctx, (object)model, model.GetType());

我想从自行设计的 API Web 服务中添加任何功能。

我想,你有一个想法,我正在尝试什么TO DO

我想定义一个函数,它可以通过将模型实例System.Object装箱并为 JSON 响应拆箱来接受来自各种数量的其他函数的调用。

它类似于reinterpret_cast<>C++ 中的函数。我认为,我可以在 C# 中使用Generics.

谢谢!

4

5 回答 5

3

这是一个不能解决但要避免的问题。事实上,将模型转换为一种类型或另一种类型是没有用的,因为当你将它传递给它时它会再次变成一个对象Serialize

只需从您的代码中完全删除这一行:

var model = sender as typeName;

JavaScriptSerializer会照顾所有的细节。

于 2013-09-26T12:18:02.273 回答
2

这会起作用..但是您应该知道,这比您可能期望的要安全得多(假设您提出了reinterpret_cast):

 var model = Convert.ChangeType(sender, typeName);

如果您只是要随机抛出类型,则可以预期会抛出异常。

于 2013-09-26T12:11:50.183 回答
1

通常的方法是静态多态性:

public static void WriteResponse<T>(ref HttpContext ctx, object sender) 
    where T : class
{
    var model = sender as T;

    // ...
}

where T : class因为T需要是引用类型 AFAIR。如果不需要,请切换到“硬”演员:

    var model = (T) sender;

或者,您可以使整个演员阵容隐含(感谢@Aik 指出)

public static void WriteResponse<T>(ref HttpContext ctx, T model) 
{
    // ...
}
于 2013-09-26T12:13:47.323 回答
0

通过在 C# 中使用泛型,您可以这样编写代码:

public static void WriteResponse<T>(HttpContext ctx, T sender)
{
    var jsonObject = new JavaScriptSerializer().Serialize(sender);
    ctx.Response.AddHeader("Access-Control-Allow-Origin", "*");
    ctx.Response.ContentType = "Content-type: application/json";
    ctx.Response.ContentEncoding = Encoding.UTF8;
    ctx.Response.Write(jsonObject);
}

internal void GetShortInfo(HttpContext ctx, Shapefile shapefile)
{
    var model = new Models.SfShortInfo
    {
        Count = shaefile.Count,
        Type = shapefile.Type.ToString()
    };

    ShapefileService.WriteResponse(ctx, model);
}

这样就不需要进行任何转换,因为它将作为它已经需要被称为的类型进入函数。

于 2013-09-26T12:16:50.447 回答
0

你根本不需要演员表。该JavaScriptSerializer.Serialize方法有这个原型:

public string Serialize(Object obj)

这意味着您的“未装箱”模型将再次装箱,而您不必这样做。该函数在内部使用反射并且能够读取所有模型元数据,即使它作为对象传递给方法。

使用refforHttpContext不是必需的,它有点危险,因为它HttpContext是引用类型,您可以在被调用的方法中更改引用。我从未见过使用 ref 关键字传递引用类型的充分理由。它主要用于值类型。

您的解决方案可能如下所示:

public static void WriteResponse(HttpContext ctx, object model)
{
    string jsonObject = new JavaScriptSerializer().Serialize(model);
    ctx.Response.AddHeader("Access-Control-Allow-Origin", "*");
    ctx.Response.ContentType = "Content-type: application/json";
    ctx.Response.ContentEncoding = Encoding.UTF8;
    ctx.Response.Write(jsonObject);
}

第二点是您不必将模型转换为object,您可以直接传递模型:

ShapefileService.WriteResponse(ctx, model);

如果您确实需要WriteResponse方法中的强类型,则可以使用泛型方法:

public static void WriteResponse<T>(HttpContext ctx, T model)
{
    string jsonObject = new JavaScriptSerializer().Serialize(model);
    ctx.Response.AddHeader("Access-Control-Allow-Origin", "*");
    ctx.Response.ContentType = "Content-type: application/json";
    ctx.Response.ContentEncoding = Encoding.UTF8;
    ctx.Response.Write(jsonObject);
}

ShapefileService.WriteResponse<Models.SfShortInfo>(ctx, model);
于 2013-09-26T12:33:47.807 回答