WCF c#中自定义类的传输问题
Posted
技术标签:
【中文标题】WCF c#中自定义类的传输问题【英文标题】:Problems with the transfer of custom class in WCF c# 【发布时间】:2019-10-17 02:25:37 【问题描述】:我正在服务器和客户端之间传输数据。客户端很容易从服务器接收到常用的数据类型,例如int
,但是如果您将自定义类传递给它,则会收到以下异常:
System.ServiceModel.CommunicationException:获取对http://127.0.0.1:8000/Service 的 HTTP 响应时出错。这可能是由于服务端点绑定不使用 HTTP 协议造成的。这也可能是由于 HTTP 请求上下文已被服务器中断(可能是由于服务被禁用)。有关详细信息,请参阅服务器日志。
我尝试了许多解决方案来解决这些问题,但没有任何帮助。
我在类字段中添加了 getter 和 setter,将 DataContract
等更改为 Serializable
:
自定义类
namespace c_CardStrategy
[DataContract]
public class Card
#region ПОЛЯ
[DataMember]
public string Name get; set;
[DataMember]
public string Effect get; set;
[DataMember]
public int ID get; set;
[DataMember]
public int Price get; set;
[DataMember]
public string EffText get; set;
#endregion
#region Конструктор
public Card(int id, string name, string effect, int price, string efftext)
Price = price;
ID = id;
Name = name;
Effect = effect;
EffText = efftext;
public Card()
Name = "";
Effect = "";
ID = 0;
Price = 0;
EffText = "";
#endregion
[DataContract]
public class Moster_Card : Card
[DataMember]
public int? Health get; set;
[DataMember]
public int? Power get; set;
public Moster_Card(int id, string name, int? health, int? power, string effect, int price, string efftext) : base(id, name, effect, price, efftext)
Health = health;
Power = power;
public Moster_Card()
Name = "";
Effect = "";
ID = 0;
Price = 0;
EffText = "";
Health = 0;
Power = 0;
[DataContract]
public class Spell_Card : Card
[DataMember]
public int? Charge get; set;
public Spell_Card(int id, string name, string effect, int price, string efftext, int? charge) : base(id, name, effect, price, efftext)
Charge = charge;
public Spell_Card()
Name = "";
Effect = "";
ID = 0;
Price = 0;
EffText = "";
Charge = 0;
界面
[ServiceContract]
public interface IGame
[OperationContract]
Players GetPlayer(int grid);
[OperationContract]
List<Players> Players();
[OperationContract]
int GetTurn(int GameGrid);
[OperationContract]
void FindGame(Players Player);
[OperationContract]
object GetAllCards();
[OperationContract]
List<Card> GetDeckOnCode(string code_deck);
[OperationContract]
bool Checkuser(string login, string pass);
[OperationContract]
void WriteInLog(string Text);
服务器
namespace c_CardStrategy
[ServiceBehavior(IncludeExceptionDetailInFaults = true)]
public class GameServer : IGame
private List<Players> listPlayers;
private List<Game> Games;
public hpartner_cgEntities context;
...
public object GetAllCards()
context = new hpartner_cgEntities();
List<Card> Cards = new List<Card>();
foreach(var Card in context.Cards)
int id = Card.Card_id;
string name = Card.Card_name;
int f = Card.Card_eff_id;
string eff;
switch (f)
case 0:
eff = "None";
break;
case 1:
eff = "Taunt";
break;
case 2:
eff = "Charge";
break;
default:
eff = "None";
break;
int price = Card.Card_price;
string efftext = Card.Card_eff_text;
int? Health = Card.Card_health;
int? Power = Card.Card_power;
int? Charge = Card.Charge;
if (Health != null)
Cards.Add(new Spell_Card(id, name, eff, price, efftext, Charge));
else
Cards.Add(new Moster_Card(id, name, Health, Power, eff, price, efftext));
return Cards;
...
客户
public partial class DecksWindow : Window
private GameClient Client;
public DecksWindow(GameClient client)
InitializeComponent();
Client = client;
private void New_deck_Click(object sender, RoutedEventArgs e)
Deck_list.Visibility = Visibility.Visible;
List<Card> Cards = new List<Card>();
try
Cards = Client.GetAllCards() as List<Card>;
foreach (Card Card in Cards)
StackPanel Sp = new StackPanel();
Sp.Height = 170;
Sp.Width = 150;
Sp.Margin = new Thickness(0, 5, 5, 0);
Sp.Background = Brushes.Red;
Sp.Tag = Card.IDk__BackingField.ToString();
Sp.Uid = 2.ToString();
Deck_list.Children.Add(Sp);
catch (Exception ex)
tb.Text += ex.Message;
//tb.Text = Client.Checkuser("Admin", "Admin").ToString();
配置客户端
<configuration>
<configSections>
<!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</configSections>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />
</startup>
<entityFramework>
<defaultConnectionFactory type="mysql.Data.Entity.MySqlConnectionFactory, MySql.Data.Entity.EF6" />
<providers>
<provider invariantName="MySql.Data.MySqlClient" type="MySql.Data.MySqlClient.MySqlProviderServices, MySql.Data.EntityFramework" />
</providers>
</entityFramework>
<connectionStrings>
<add name="hpartner_cgEntities" providerName="System.Data.EntityClient" connectionString="metadata=res://*/Model.csdl|res://*/Model.ssdl|res://*/Model.msl;provider=MySql.Data.MySqlClient;provider connection string="server=hpartnerlink.ru;user id=hpartner;password=M7gn46Wx3b;persistsecurityinfo=True;database=hpartner_cg"" />
</connectionStrings>
<system.web>
<httpRuntime maxRequestLength="262144" executionTimeout="103600"/>
</system.web>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_IGame" />
<binding name="BasicHttpBinding_IGame1" />
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://127.0.0.1:8000/Service" binding="basicHttpBinding"
bindingConfiguration="BasicHttpBinding_IGame" contract="GameServiceReference.IGame"
name="BasicHttpBinding_IGame" />
<endpoint address="http://0.0.0.0:8000/Service" binding="basicHttpBinding"
bindingConfiguration="BasicHttpBinding_IGame1" contract="ServiceReference1.IGame"
name="BasicHttpBinding_IGame1" />
</client>
</system.serviceModel>
配置服务器
<configSections>
<!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</configSections>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />
</startup>
<entityFramework>
<defaultConnectionFactory type="MySql.Data.Entity.MySqlConnectionFactory, MySql.Data.Entity.EF6" />
<providers>
<provider invariantName="MySql.Data.MySqlClient" type="MySql.Data.MySqlClient.MySqlProviderServices, MySql.Data.EntityFramework" />
</providers>
</entityFramework>
<connectionStrings>
<add name="hpartner_cgEntities" providerName="System.Data.EntityClient" connectionString="metadata=res://*/Model.csdl|res://*/Model.ssdl|res://*/Model.msl;provider=MySql.Data.MySqlClient;provider connection string="server=hpartnerlink.ru;user id=hpartner;password=M7gn46Wx3b;persistsecurityinfo=True;database=hpartner_cg"" />
</connectionStrings>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="debug">
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service name="MyServiceName" behaviorConfiguration="debug" />
</services>
</system.serviceModel>
【问题讨论】:
您的Card
类必须是DataContract
,以便您可以在客户端看到class
。每个属性也需要DataMember
属性。请注意,我从未在WCF
服务中使用过派生类,所以我不确定派生类是否也需要DataContract
,但我相信它也应该拥有它。
@Franck,已经这样做了,但没有帮助[DataContract] public class Card #region ПОЛЯ [DataMember] public string Name get; set; [DataMember] public string Effect get; set; ...
我知道这对您的错误没有帮助。但是您的代码将需要它在客户端工作,因为您具有该对象的返回类型。如果类不是DataContract
和DataMember
,它将不起作用。您的错误是与您的绑定有关的通信错误。您需要将您的 web.config
添加到帖子中,以便有人可以提供帮助。
@Franck,更新了主题,添加了配置。感谢您的提示
我怀疑你的服务器正在使用你的客户端正在使用的 basicHttpBinding。
【参考方案1】:
您可以在托管服务后访问 Web 服务的 WSDL 吗? 我怀疑配置可能太简单了。我建议您在服务器端应用以下配置。
<system.serviceModel>
<services>
<service name="YourNamespace.GameServer " behaviorConfiguration="mybehavior">
<endpoint address="http://localhost:8000/Service" binding="basicHttpBinding" contract="YourNamespace.IGame " ></endpoint>
<endpoint address="http://localhost:8000/Service/mex" binding="mexHttpBinding" contract="IMetadataExchange"></endpoint>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="mybehavior">
<serviceMetadata httpsGetEnabled="true" httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
托管服务后,我们可以通过在浏览器地址栏中输入服务地址来访问服务信息。
http://localhost:8000/service
此外,我们在托管服务时可能需要管理权限。 如果问题仍然存在,请随时告诉我。
【讨论】:
以上是关于WCF c#中自定义类的传输问题的主要内容,如果未能解决你的问题,请参考以下文章